1. 背景
上一篇我们分析了
Lifecycles
组件的源码,本篇我们将继续分析LiveData
组件
相关系列文章:
1. Jetpack源码解析—看完你就知道Navigation是什么了?
2. Jetpack源码解析—Navigation为什么切换Fragment会重绘?
3. Jetpack源码解析—用Lifecycles管理生命周期
2. 基础
2.1 简介
LiveData
是一个可观察的数据持有者类,与常规observable
不同,LiveData
是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如Activity
,Fragment
或Service
。此感知确保LiveData
仅更新处于活动生命周期状态的应用程序组件观察者。
2.2 优点
1. 确保UI符合数据状态
LiveData遵循观察者模式。 当生命周期状态改变时,LiveData会向Observer发出通知。 您可以把更新UI的代码合并在这些Observer对象中。不必去考虑导致数据变化的各个时机,每次数据有变化,Observer都会去更新UI。
2. 没有内存泄漏
Observer会绑定具有生命周期的对象,并在这个绑定的对象被销毁后自行清理。
3. 不会因停止Activity而发生崩溃
如果Observer的生命周期处于非活跃状态,例如在后退堆栈中的Activity,就不会收到任何LiveData事件的通知。
4.不需要手动处理生命周期
UI组件只需要去观察相关数据,不需要手动去停止或恢复观察。LiveData会进行自动管理这些事情,因为在观察时,它会感知到相应组件的生命周期变化。
5. 始终保持最新的数据
如果一个对象的生命周期变到非活跃状态,它将在再次变为活跃状态时接收最新的数据。 例如,后台Activity在返回到前台后立即收到最新数据。
6. 正确应对配置更改
如果一个Activity或Fragment由于配置更改(如设备旋转)而重新创建,它会立即收到最新的可用数据。
7.共享资源
您可以使用单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享。LiveData对象一旦连接到系统服务,任何需要该资源的Observer都只需观察这个LiveData对象。
2.3 基本使用
在我们的Jetpack_Note中有使用demo,具体可查看LiveDataFragment。
Demo中通过对一个LiveData对象进行生命周期的监听,实现将值打印在控制台中。首先声明一个LiveData对象:
private lateinit var liveData: MutableLiveData<String>
点击开始观察数据按钮,弹出控制台,我们可以看到控制台输出了onStart()
日志,因为我们将liveData的值和Fragment的生命周期进行了绑定,当返回桌面或者销毁Fragment的时候,LiveData的值会变成相应的生命周期函数,并打印在控制台中:
class LiveDataFragment : Fragment() {
private lateinit var liveData: MutableLiveData<String>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_live_data, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
liveData = MutableLiveData()
btn_observer_data.setOnClickListener {
if (FloatWindow.get() == null) {
FloatWindowUtils.init(activity?.application!!)
}
FloatWindowUtils.show()
//创建一个观察者去更新UI
val statusObserver = Observer<String> {
lifeStatus ->
FloatWindowUtils.addViewContent("LiveData-onChanged: $lifeStatus")
}
liveData.observeForever(statusObserver)
}
}
override fun onStart() {
super.onStart()
liveData.value = "onStart()"
}
override fun onPause() {
super.onPause()
liveData.value = "onPause()"
}
override fun onStop() {
super.onStop()
liveData.value = "onStop()"
}
override fun onDestroy() {
super.onDestroy()
liveData.value =