前提
LiveData使用了Lifecycle的生命周期,阅读本文前,请先了解Lifecycle源码。
简介
LiveData本质是数据类型,当改变数据的时候,会通知观察者,且只在界面可见的时候才会通知观察者。只能在主线程注册观察者,一般用于更新UI。
具有生命周期属性,生命周期属性来源于Lifecycle的功能。
具有数据粘性,先改变数据,再注册观察者,能收到上一次数据的改变。
使用
普通使用
界面TextView先被改为“我是info1”,1s后改为“在子线程中修改info1”。
界面可见才接收数据
只有在界面可见的时候,观察者才接收数据,中间数据会被丢弃。
执行结果:
先修改数据,后添加观察者,能收到最后一个修改的数据
数据粘性,先修改LiveData数据,再给LiveData添加观察者,该观察者能接收到LiveData最后一次修改的数据。
运行结果:
如何去除粘性?
hook反射 动态修改源码,去除粘性。
源码分析
相关类有LiveData和MutableLiveData,LiveData是抽象类,核心代码在此类中实现。MutableLiveData类是提供给用户使用的,提供修改数据方法。
订阅观察者
订阅观察者的时候,要传入LifecycleOwner对象和Observer对象,在Lifecycle源码分析时,可知LifecycleOwner对象就是Activity。
订阅观察者的时候做了两件事情。
创建Lifecycle的观察者LifecycleBoundObserver,并注册。
存储LiveData观察者用于通知。
修改LiveData数据的时候,如何通知观察者?
主线程修改LiveData数据
主线程修改LiveData数据通知观察者流程,整个过程都在主线程中执行。
子线程修改LiveData数据
子线程修改LiveData数据的时候,首先要使用锁保证value的正确,然后使用Handler切换至主线程,使用主线程修改LiveData数据的方法setValue修改数据。
粘性原理
除了上述流程外,因为使用Lifecycle监听了Activity的生命周期,那么当生命周期回调的时候做了哪些事情?
在订阅观察者的时候,可知Lifecycle的观察者是LifecycleBoundObserver,来监听Activity的生命周期变化。
查看下LifecycleBoundObserver源码如下:
如何去除粘性,使用Hook修改LiveData观察者(ObserverWrapper)的版本和LiveData类的版本(mVersion)相等即可。