LiveData简介
LiveData综述
LiveData是Google Jetpack组件中的一员,是一种可观察的数据存储器类。但是与常规的观察类不同,LiveData具有生命周期感知的能力,
如Fragment、Activity、Service的生命周期等,可以根据需要只在生命周期活跃内更新被观察者的组件,当然也可以常驻观察,根据需求而定。
LiveData相关的类
- LiveData.java类,核心类,实现核心的数据存储于观察。
- MutableLiveData.java类,LiveData.java的继承类,对外公开了set和post值的方法。
- Observer.java接口,接口,可以接受从LiveData接收简单的回调。
- 声明并创建MutableLiveData对象
- 创建Observer观察者对象
- 订阅操作
- 调用MutableLiveData对象的post、set方法发送内容,则在Observer对象的回调方法中可以收到回调。
代码如下:
class TestActivity :AppCompatActivity(){private lateinit var liveData:MutableLiveData>override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test_live_data)
liveData = https://www.it610.com/article/MutableLiveData()val statusObserver = Observer>{
Log.d(Common.TAG,it)
}
// 订阅传入了this(LifecycleOwner)对象,
//可根据生命周期进行接受信息
//onResume之前和onPause之后不接受消息
liveData.observe(this,statusObserver)
liveData.value = "https://www.it610.com/article/onCreate()"}override fun onStart() {
liveData.value = "https://www.it610.com/article/onStart()"
}override fun onResume() {
super.onResume()
liveData.value = "https://www.it610.com/article/onResume()"
}override fun onPause() {
super.onPause()
liveData.value = "https://www.it610.com/article/onPause()"
}override fun onStop() {
super.onStop()
liveData.value = "https://www.it610.com/article/onStop()"
}override fun onDestroy() {
super.onDestroy()
liveData.value = "https://www.it610.com/article/onDestroy()"
}}
日志如下:
文章图片
文章图片
onResume和onPause收到消息正常
点击按钮在 onResume和onPause之间收到消息也正常
为什么onStart也打印出来了呢?注意:*set方法只能在主线程调用,post方法不受限制。 1. 子线程使用setValue方法,代码如下:
这是另外一个机制:
如果在非活跃期间收到消息,则会缓存最新的一条消息,在状态由非活跃变为活跃的时候收到缓存的最新消息
这就是onStart打印出来的原因。
可以这样验证
去掉onStart的setValue 留下onCreate的setValue,则打印出来的就是onCreate了,我们都知道onCreate是肯定不在活跃状态的,之所以
刚才打出来的是onStart,那是因为onStart覆盖了onCreate所致,只会缓存最新的一条信息
override fun onStart() {
super.onStart()
Thread(Runnable {
liveData.value = "https://www.it610.com/article/onStart()"
}).start()}
运行直接报错如下:
文章图片
原因在源码中直接就能找到(LiveData部分源码如如下):
/**
* Sets the value. If there are active observers, the value will be dispatched to them.
* * 注释写的很清楚,必须在主线程调用该方法
* This method must be called from the main thread. If you need set a value from a background
* thread, you can use {@link #postValue(Object)}
*
* @param value The new value
*/
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = https://www.it610.com/article/value;
dispatchingValue(null);
}
1、注释写的很清楚,必须在主线程调用该方法
2、@MainThread注解,标注该方法必须在主线程调用
2. 子线程和主线程分别使用postValue方法,代码如下:
override fun onStart() {
super.onStart()
Thread(Runnable {
liveData.postValue( "onStart()")
}).start()}override fun onResume() {
super.onResume()
liveData.postValue( "onResume()")
}
直接运行,日志如下:
文章图片
1、标注1是在子线程postValue没有问题
2、注释2是在主线程postValue也没有问题
源码
【Android Jetpack之LiveData】源码链接:源码
总结:
LiveData暂时介绍到此
自勉,遇到问题的时候多查资料,研究源码,不要着急下定论:
比如上述的onStart打印出来,并不是因为此处能收到消息,而是消息的缓存机制。
比如上述的setValue不能在子线程调用,直接在源码中就能明确看到说明与注解。