jetpack小记

jetpack知识点记录整理


目前存在官方bug,BottomNavigationView点击切换时,fragment重复执行onCreateView

目前只是单纯使用BottomNavigationView来手动切换fragemnt,show / hide

LifeCycle

用于帮助开发者管理Activity和Fragment 的生命周期,它是LiveData和ViewModel的基础。
比如需要在特定生命周期中开启或者关闭的组件,方便管理

功能组件 实现 LifecycleObserver 接口,自动感知生命周期,组件处理自己逻辑,减轻Activity/Fragment中代码

Application也可以使用LifeCycle
MyApp: ON_START – onAppForeground
MyApp: ON_STOP – onAppBackground

Activity/Fragment用的是
lifecycle.addObserver(自定义Observer)
Application用的是
ProcessLifecycleOwner.get().lifecycle.addObserver(自定义Observer)

ComponentActivity实现了LifecycleOwner接口
创建Lifecycle子类LifecycleRegistry
创建了ReportFragment,这个Fragment的作用就是用来分发生命周期状态的。
在ReportFragment的每个生命周期的回调中,都对应的调用了 dispatch 方法 ,来进行状态分发。
最后 dispatch的方法中,又调用了 LifecycleRegistry 的handleLifecycleEvent

livedata

LiveData 具有生命周期感知能力

  1. LiveData是一个数据持有者,给源数据包装一层。
  2. 源数据使用LiveData包装后,可以被observer观察,数据有更新时observer可感知。
  3. 但 observer的感知,只发生在(Activity/Fragment)活跃生命周期状态(STARTED、RESUMED)即activity onStart——onPause之间处于激活状态。

livedata会自动管理观察者observer,不需手动接触,不会内存泄漏

MyLiveData.get().observe(this, {
Log.d(TAG, “MyLiveData onChanged : $it”)
})

owner.getLifecycle().addObserver(wrapper);
owner就是this,wrapper是用LifecycleBoundObserver包装的Observer
内部就是用了lifecycle

LivaData数据更新可以使用setValue(value)、postValue(value)
区别在于postValue(value)用于子线程,使用setValue()、postValue()更新数据时会通知回调所有的观察者。

viewmodel

ViewModel生命周期长于Activity,因系统配置变更Activity销毁重建,ViewModel对象会保留并关联到新的Activity。
而Activity的正常销毁(系统不会重建Activity)时,ViewModel对象是会清除的。

和lifecycle一样,ComponentActivity实现了ViewModelStoreOwner接口
ComponentActivity拥有变量ViewModelStore,它将viewModel作为Value存储在HashMap中。

kotlin采用 val homeViewModel: HomeViewModel by viewModel() 委托模式创建
内部:先尝试从ViewModelStore获取ViewModel实例,如果没有获取到,就使用Factory创建,然后存入ViewModelStore。

配置改变时 系统把viewModelStore存在了NonConfigurationInstances中

  1. 其中NonConfigurationInstances是ComponentActivity静态内部类,非配置实例
    static final class NonConfigurationInstances {
    Object custom;
    ViewModelStore viewModelStore;
    }

  2. ActivityThread 中的 ActivityClientRecord 是不受 activity 重建的影响,那么ActivityClientRecord中lastNonConfigurationInstances也不受影响,那么其中的Object activity也不受影响,那么ComponentActivity中的NonConfigurationInstances的viewModelStore不受影响,那么viewModel也就不受影响了

上述两点说明 viewmodel 生命周期大于activity
条件:在配置发生变化而销毁activity时
正常销毁 ActivityClientRecord 也会回收的,vm自然也没了

ViewModel是存在内存中,读写速度快,而通过onSaveInstanceState是在 序列化到磁盘中。

ViewModel,可以存复杂数据,大小限制就是App的可用内存。而 onSaveInstanceState只能存可序列化和反序列化的对象,且大小有限制(一般Bundle限制大小1M)。

databing

目前只用来 不写 findviewbyid

flow

1.Flow通过flowOn改变数据发射的线程,数据消费线程则由协程所在线程决定
2.Flow没有提供取消方法,可以通过取消Flow所在协程的方式来取消

LiveData仍然可以作为响应式编程的架构组件,只是更复杂的场景(数据处理,多个请求合并等等)使用 Flow 来实现更合适

背压:当下游的消费者的速率小于上游生产者的速率时,生产者就会收到来自消费者的背压。

runBlocking {
flow {
(1..5).forEach {
delay(200)
println(“emit$it,${System.currentTimeMillis()},${Thread.currentThread().name}”)
emit(it)
}
}.buffer().collect {
delay(500)
println(“collect$it,${System.currentTimeMillis()},${Thread.currentThread().name}”)
}
}

解决背压:
1.buffer(flowon切换线程效果也一样)
缓冲
2.conflate
消费完才会消费目前最新的数据
消费完一个数据,conflate才会发送此时的新数据
不会打断消费者消费过程
3.collectLatest
在最新值来的时候,将当前消费者的消费过程取消,然后令消费者处理最新值。

实操:
flow {
// 进行网络或者数据库操作
emit(model)
}.flowOn(Dispatchers.IO) // 通过 flowOn 切换到 IO 线程