Android第二次面试总结(项目拷打理论篇)

(一)理论基础

LiveDataViewModel 是 Android 架构组件中的重要部分,它们在构建响应式、生命周期感知的 Android 应用程序中发挥着关键作用。下面分别介绍它们的原理。

LiveData 原理

1. 概述

LiveData 是一种可观察的数据持有者类,它具有生命周期感知能力,这意味着它能遵循其他应用组件(如 ActivityFragment)的生命周期。只有处于活跃状态(如 STARTEDRESUMED)的观察者才能收到数据更新的通知。

2. 核心组成部分
  • LiveData:作为数据的持有者,它内部维护了一个数据对象和一个观察者列表。
  • Observer 接口 :定义了一个 onChanged(T t) 方法,当 LiveData 中的数据发生变化时,会调用该方法通知观察者。
  • LifecycleOwner 接口 :表示具有生命周期的对象,如 ActivityFragment 都实现了该接口。LiveData 通过 Lifecycle 来感知 LifecycleOwner 的生命周期状态。
3. 工作原理
  • 注册观察者 :当调用 LiveData.observe(LifecycleOwner owner, Observer<? super T> observer) 方法时,LiveData 会将 LifecycleOwnerObserver 包装成一个 LifecycleBoundObserver 对象,并将其添加到观察者列表中。同时,LifecycleBoundObserver 会监听 LifecycleOwner 的生命周期变化。
java 复制代码
// Java 示例
LiveData<String> liveData = new MutableLiveData<>();
observe(lifecycleOwner, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        // 处理数据变化
    }
});
  • 生命周期感知LifecycleBoundObserver 实现了 LifecycleEventObserver 接口,当 LifecycleOwner 的生命周期状态发生变化时,LifecycleBoundObserver 会收到相应的事件通知。如果 LifecycleOwner 进入活跃状态(STARTEDRESUMED),LiveData 会将最新的数据发送给该观察者;如果 LifecycleOwner 进入销毁状态(DESTROYED),LiveData 会自动移除该观察者,以避免内存泄漏。
  • 数据更新 :当调用 LiveData.setValue(T value)LiveData.postValue(T value) 方法更新数据时,LiveData 会检查所有观察者的生命周期状态,只有处于活跃状态的观察者才会收到 onChanged 方法的调用。

ViewModel 原理

1. 概述

ViewModel 旨在存储和管理与 UI 相关的数据,并且在配置更改(如屏幕旋转)时保持数据的一致性。它的生命周期比 ActivityFragment 更长,直到关联的 ActivityFragment 被销毁(对于 ActivityonDestroy() 调用且不是由于配置更改;对于 FragmentonDestroy() 调用)。

2. 核心组成部分
  • ViewModel :开发者自定义的 ViewModel 类需要继承自 ViewModel 类,用于存储和管理与 UI 相关的数据。
  • ViewModelProvider :负责创建和管理 ViewModel 实例。它使用 ViewModelStore 来存储 ViewModel 实例。
  • ViewModelStore :是一个简单的键值对存储结构,用于存储 ViewModel 实例。每个 ActivityFragment 都有一个对应的 ViewModelStore
3. 工作原理
  • 创建 ViewModel 实例 :当调用 ViewModelProvider(owner).get(MyViewModel.class) 方法时,ViewModelProvider 会首先检查 ViewModelStore 中是否已经存在指定类型的 ViewModel 实例。如果存在,则直接返回该实例;如果不存在,则使用 ViewModelProvider.Factory 创建一个新的 ViewModel 实例,并将其存储在 ViewModelStore 中。
java 复制代码
// Java 示例
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
MyViewModel viewModel = viewModelProvider.get(MyViewModel.class);
  • 配置更改时数据保留 :当发生配置更改(如屏幕旋转)时,ActivityFragment 会被销毁并重新创建,但 ViewModelStore 会被保留。因此,重新创建的 ActivityFragment 可以从 ViewModelStore 中获取之前的 ViewModel 实例,从而保持数据的一致性。
  • 生命周期管理 :当 ActivityFragment 被销毁(不是由于配置更改)时,ViewModelStore 会调用 clear() 方法,该方法会遍历所有存储的 ViewModel 实例,并调用它们的 onCleared() 方法,以便进行资源释放。

LiveData 是具有生命周期感知能力的数据持有者,通过监听 LifecycleOwner 状态更新活跃观察者,ViewModel 借助 ViewModelProviderViewModelStore 存储管理 UI 数据,在配置更改时保留数据并在关联组件非配置更改销毁时清理资源。

下一阶段

Room 是 Android 官方提供的一个 SQLite 对象映射库,用于在 Android 应用中简化数据库操作,WorkManager 是 Android 架构组件之一,用于在应用中调度和管理后台任务。

Room 工作原理

  • 抽象层封装 :Room 提供了一个抽象层,将 SQLite 数据库的操作抽象成 Java 或 Kotlin 接口和注解。开发者可以通过定义实体类(@Entity)、数据访问对象(@Dao)和数据库类(@Database)来描述数据库结构和操作。
  • 编译时处理:在编译时,Room 会根据开发者定义的注解生成相应的 SQLite 语句和实现代码。这样可以在编译时发现数据库操作中的错误,提高开发效率和代码的健壮性。
  • 线程管理:Room 默认不允许在主线程中执行数据库操作,因为数据库操作通常是耗时的,可能会导致 UI 卡顿。因此,Room 会将数据库操作放在后台线程中执行。

定义实体类

Kotlin 复制代码
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "users")
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val name: String,
    val age: Int
)

定义数据访问对象(DAO)

Kotlin 复制代码
import androidx.room.Dao
import androidx.room.Insert

@Dao
interface UserDao {
    @Insert
    suspend fun insertUser(user: User)
}

定义数据库类

Kotlin 复制代码
import androidx.room.Database
import androidx.room.RoomDatabase

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}
WorkManager 工作原理
  • 任务调度:WorkManager 会根据任务的约束条件(如网络连接、电池状态等)和设备的当前状态来决定何时执行任务。它会尽量在设备处于空闲状态时执行任务,以减少对用户体验的影响。
  • 任务持久化:WorkManager 会将任务信息持久化到本地数据库中,即使应用被杀死或设备重启,任务信息也不会丢失。当设备满足任务的约束条件时,WorkManager 会重新调度任务执行。
  • 生命周期管理:WorkManager 会自动处理任务的生命周期,包括任务的执行、重试和取消等操作。它会根据任务的状态(如运行中、已完成、失败等)更新任务信息。

创建 WorkManager 任务

Kotlin 复制代码
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import kotlinx.coroutines.runBlocking

class InsertUserWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        val database = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java,
            "app-database"
        ).build()
        val userDao = database.userDao()

        val user = User(name = "John", age = 30)
        runBlocking {
            userDao.insertUser(user)
        }

        return Result.success()
    }
}

调度 WorkManager 任务

Kotlin 复制代码
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val workRequest = OneTimeWorkRequest.Builder(InsertUserWorker::class.java).build()
        WorkManager.getInstance(this).enqueue(workRequest)
    }
}
Room + WorkManager 协同工作原理
  • 数据交互:WorkManager 可以在后台任务中执行 Room 数据库操作,如插入、查询、更新和删除数据。这样可以避免在主线程中执行耗时的数据库操作,提高应用的性能和响应速度。
  • 任务调度:当应用需要在特定条件下执行数据库操作时,可以使用 WorkManager 来调度这些任务。例如,当设备连接到网络时,执行数据同步任务,将本地数据库中的数据上传到服务器。
  • 数据一致性:由于 WorkManager 会保证任务的执行,即使应用在任务执行过程中被杀死或设备重启,任务也会在合适的时机继续执行。这样可以确保数据库操作的完整性和数据的一致性。

总结:

Room 作为 Android 的 SQLite 对象映射库,在编译时根据注解生成数据库操作代码并管理线程,WorkManager 依据任务约束和设备状态调度持久化的后台任务,二者结合时 WorkManager 可在后台任务里执行 Room 的数据库操作,保障数据一致性,实现时先添加依赖,再定义 Room 数据库,创建 WorkManager 任务,最后调度任务执行。

下一篇我将讲述面试中我被项目拷打到的点!!!

感谢观看!!!

相关推荐
锋风18 分钟前
音视频缓存数学模型
android
_一条咸鱼_21 分钟前
深入剖析 Android Dagger 2 框架的注解模块(一)
android
小白马丶22 分钟前
Jetpack源码解读(二)——LiveData
android·android jetpack
TDengine (老段)23 分钟前
TDengine 特色查询
android·大数据·数据库·物联网·时序数据库·tdengine·iotdb
锋风23 分钟前
安卓屏保调试
android
程序员江同学1 小时前
如何给 Kotlin 新增一个 target?
android·kotlin
shuangrenlong2 小时前
安卓编译问题
android
Bonnie_cat3 小时前
Android Framework 之了解系统启动流程二
android
Android采码蜂3 小时前
SurfaceFlinger11-ITransactionCompletedListener事件监听
android
奥顺互联V4 小时前
如何处理PHP中的编码问题
android·开发语言·php