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 任务,最后调度任务执行。

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

感谢观看!!!

相关推荐
姜行运32 分钟前
数据结构【二叉搜索树(BST)】
android·数据结构·c++·c#
JhonKI8 小时前
【MySQL】存储引擎 - CSV详解
android·数据库·mysql
开开心心_Every8 小时前
手机隐私数据彻底删除工具:回收或弃用手机前防数据恢复
android·windows·python·搜索引擎·智能手机·pdf·音视频
大G哥9 小时前
Kotlin Lambda语法错误修复
android·java·开发语言·kotlin
鸿蒙布道师12 小时前
鸿蒙NEXT开发动画案例2
android·ios·华为·harmonyos·鸿蒙系统·arkui·huawei
androidwork13 小时前
Kotlin Android工程Mock数据方法总结
android·开发语言·kotlin
xiangxiongfly91515 小时前
Android setContentView()源码分析
android·setcontentview
人间有清欢16 小时前
Android开发补充内容
android·okhttp·rxjava·retrofit·hilt·jetpack compose
人间有清欢17 小时前
Android开发报错解决
android
每次的天空18 小时前
Android学习总结之kotlin协程面试篇
android·学习·kotlin