一、介绍
SavedStateHandle从名字可以看出,是保存状态的。这个类常和MVVM中的ViewModel搭配使用,对页面生命周期的数据状态的缓存与恢复做一个容器。这个容易相对onSaveInstanceState(Bundle)要更强一点,保存的数据类型也比较丰富,数据量也相对较大
二、分析
分析一个类,最简单的就是从源码看起:
2.1容器集合
- regular = mutableMapOf
- savedStateProviders = mutableMapOf
- liveDatas = mutableMapOf
- flows = mutableMapOf
以上都是map集合,都是用来存放key-value,四种集合对应四种不同的场景。
2.2 AIP的介绍
fun <K> set(key: String, value: K, bundle: Bundle) {
state.set(key, value)
state.setSavedStateProvider(key, MyProvider(bundle))
state.set(key, MyStateFlow<K>())
}
fun <M> get(key: String) {
state.get<M>(key)
state.getLiveData<M>(key)
var initialValue: M? = null
state.getLiveData(key, initialValue)
state.getStateFlow(key, initialValue)
}
通过数据保存,我们会发现,set的时候没有LiveData类型,那是因为在set的方法时,会对livedata集合进行单独处理
源码
三、类的介绍
3.1 SavedStateRegistry.SavedStateProvider
该类是一个接口,这个接口提供了一个方法,就是可以返回bundle对象。所以,原来的bundle对象是通过该方法进行保存
3.2 StateFlow
flow为流,stateflow为状态流。在软件生命周期中,字节和流一直是比较常见的资源,特别是流,可以伴随着任何业务和模块。
SavedStateHandle同样也支持流的保存。
关于SateFlow使用了out,我将对out和in做一下解释
out:
在 kotlin 中用 out 表示,kotlin 中的 “out T” 等同于 Java 的 <?extends T>
in:
在 kotlin 中用 in 表示,kotlin 中的 “in T” 等同于 Java 的 <?super T>
internal class MyStateFlow<out A> : StateFlow<A> {
//重复缓存的快照
override val replayCache: List<A>
get() = TODO("Not yet implemented")
/**
* 接受给定的收集器并将值发送到其中。要将值从共享流发送到特定收集器,可以使用collecter.emitAll(流)或collect{…}SAM转换。
共享流永远不会完成。对Flow.collector或共享流上的任何其他终端操作员的调用从未正常完成。
* */
override suspend fun collect(collector: FlowCollector<A>): Nothing {
TODO("Not yet implemented")
var a:A
collector.emit(a)
}
//此状态流的当前值
override val value: A
get() = TODO("Not yet implemented")
}
四、总结
在数据保存的地方,分两种保存方法,但是在数据存储的地方,分四种。所以,不管在保存还是恢复,都需要严格执行SavedStateHandle的规则。
标签:set,MVVM,SavedStateHandle,get,保存,state,key,Android,out From: https://blog.51cto.com/u_16065093/6182721