# Android Jetpack面试

By [Peusoar](https://paragraph.com/@peusoar-2) · 2022-11-27

---

> ### Lifecycle

    1. 生命周期感知型组件可执行操作来响应另一个组件（如activity和fragment）的生命周期状态的变化。有助于写出更有条理且往往更精简的代码，这样的代码更易于维护
    2. LifecycleOwner（被观察者）和LifecycleObserver（观察者）。即通过观察者模式，实现对页面生命周期的监听->getLifecycle().addObserver()绑定两者
    3. @OnLifecycleEnet(Lifecycle.Event.*) 来感知6个生命周期的方法
    4. 里面用一个空的ReportFragment来管理生命周期的，通过dispatch派发所有生命周期方法
    5. 里面有一个状态机来管理生命周期的变化：可见到不可见；不可见到可见
    6. LifecycleService来管理service的生命周期
    7. ProcessLifecycleOwner监听应用程序的生命周期
    
    viewmodel：
      a. 瞬态数据丢失
      b. 异步调用的内存泄露
      c. 类膨胀提高维护和测试难度
    
    androidx.lifecycle.LiveData：
      a. LiveData 是一种可观察的数据存储器类，具有生命周期感知能力
      b. 确保界面符合数据状态;不会发生内存泄漏;不会因 Activity 停止而导致崩溃;不再需要手动处理生命周期;数据始终保持最新状态;适当的配置更改;共享资源
      c. 用法：liveData.observe(this, new Observer<String>())
    LiveData与MutableLiveData区别:
      a. MutableLiveData的父类是LiveData
      b. LiveData在实体类里可以通知指定某个字段的数据更新
      c. MutableLiveData则是整个实体类或者数据类型变化后才通知.不会细节到某个字段
    MediatorLiveData:
      a. 它可以统一观察多个 LiveData 的发射的数据进行统一的处理；同时也可以作为一个 LiveData，被其他 Observer 观察。
    
    LiveData的不足
      a. LiveData 只能在主线程更新数据： 只能在主线程 setValue，即使 postValue 内部也是切换到主线程执行
      b. LiveData 数据重放问题： 注册新的订阅者，会重新收到 LiveData 存储的数据，这在有些情况下不符合预期（可以使用自定义的 LiveData 子类 SingleLiveData 或 UnPeekLiveData 解决） 
      c. LiveData 不防抖： 重复 setValue 相同的值，订阅者会收到多次 onChanged() 回调（可以使用 distinctUntilChanged() 解决）
      d. LiveData 不支持背压： 在数据生产速度 > 数据消费速度时，LiveData 无法正常处理。比如在子线程大量 postValue 数据但主线程消费跟不上时，中间就会有一部分数据被忽略
    kotlin Flow优势：
      a. Flow 支持协程： Flow 基于协程基础能力，能够以结构化并发的方式生产和消费数据，能够实现线程切换（依靠协程的 Dispatcher）
      b. Flow 支持背压： Flow 的子类 SharedFlow 支持配置缓存容量，可以应对数据生产速度 > 数据消费速度的情况
      c. Flow 支持数据重放配置： Flow 的子类 SharedFlow 支持配置重放 replay，能够自定义对新订阅者重放数据的配置
      d. Flow 不是生命周期感知型组件
    

> ### Databinding

    数据绑定，是mvvm模式在Android上的实现
    布局： <layout><data></data>.....</layout>
    双向数据绑定的三种方式：
      a. BaseObservable
      b. ObseravbleField
      c. ObseravbleCollection
    

> ### Room

    ORM库，主要是对Sqlite做了一层抽象，从而简化开发者对数据库操作。Room支持编译时的语法检查，并且支持返回LiveData
    主要概念：
      1. Entity：实体类，对应的是数据库的一张表
      2. Dao：一系列访问数据库的方法
      3. Database：数据库持有者，作为与应用持久化相关数据的底层连接，继承RoomDatabase
    升级数据库：Migration
    

> ### Navigation

    1. 通过NavigationUI对菜单、底部导航、抽屉菜单导航进行统一管理
    2. 可视化的页面导航图
    3. 方便添加页面切换动画
    4. 页面间类型安全的传参
    5. 支持深层链接DeepLink
    元素：
    Navigation Graph 一种新的xml资源文件，包含应用程序所有的页面以及页面间的关系
    NavHostFragment 一个特性的fragment，是其它fragment的容器
    NavController 用于在代码中完成NavigationGraph中具体的页面切换工作
    safeArgs传参：
    缺点：fragment切换后底层会调用replace方法导致会被不断销毁，无法保存上一次的状态
    

> ### WorkManager

    workManager为应用程序中那些不需要及时完成的任务提供了一个统一的解决方案，以便在设备电量和用户体验之间达到一个比较好的平衡
    能保证任务一定会执行，哪怕程序退出了
    在api23+ 采用的是JobScheduler 以下采用的是AlarmManager+BroadcastReceiver
    使用：
      1. extends Worker 实现 doWork 方法 返回 Result
      2. wm = WorkManager.getInstance(this)
      3. wm.enqueue(wrok) 添加任务 之前要配置任务：OneTimeWorkRequest.Builder 里面可以配置约束 Constraints ：网络，延时、退避策略、tag标签、参数传递Data
      4. 观察任务状态 wm.getWorkInfoByIdLiveData(wq.getId).observe
      5. 取消任务wm.cancelWorkById(wq.getId)
      6. 周期性任务 PeriodicWorkRequest
      7. 任务链 Request.Builder beginWith(a).then(b) 先a后b
      8. 任务组合: 先 组合多个任务的WorkContinuation -> List -> WorkContinuation.combine(list).enqueue()
    

> ### Paging

    PagedListAdapter: 适配器
    PagedList：负责通知DataSource何时获取数据，以及如何获取数据，从DataSource获取的数据将存储在PagedList中
    DataSource：执行具体的数据载入工作，可以来自网络，数据库，通过了3中DataSource
      a. PositionDataSource:适用于可通过任意位置加载数据且目标数据数量固定的情况（DataSource.Factory -> LivePagedListBuilder）
      b. PageKeyedDataSource: 适用于数据源以页的方式请求的情况
      c. ItemKeyedDataSource：适用于党目标数据的下一页需要依赖上一页的数据中最后一个对象中的某个字段作为key的情况
    
    BoundaryCallback

---

*Originally published on [Peusoar](https://paragraph.com/@peusoar-2/android-jetpack)*
