入门文章. 本文纯属个人见解, 请谨慎阅读.
本文回答这个问题:
Jetpack 中的 LiveData 到底是啥, Google 希望开发者怎么用?
LiveData
-
什么是 LiveData?
Live - 活的; 直播
Data - 数据
活的, 数据? 直播数据? 这是啥?这是有活力的数据!
普通的数据, 就是创建一个变量, 保存一些值. 比如 string 或 int 等. 当代码改变他们的值之后, 他们的值就被改变了.. 废话.. 但是然后就没有然后了.
那么有活力的数据有什么不同呢?
有活力的数据的不同之处在于, 他在改变之后会通知所有对他感兴趣的人
从代码上看就是, 在数据被重新 set 值之后, 会调用到指定的回调方法.LiveData 他跟其他普通的变量没有什么不同, 都是保存着一些值的数据.
但他却有不同, 不同之处就在于他可以非常方便的维护一系列对他的数据感兴趣的对象.
当他的数据被改变的时候就会通知到所有对这个数据感兴趣的对象, 并执行这些对象中的部分代码块.对, 这些代码块也就是回调方法.
对, 这些感兴趣的对象就是 LiveData 的观察者们.
-
观察者是什么意思不清楚? 一句话说清楚什么是观察者
中央电视台和北京电视台都关心北京天气. 北京天气就是被观察者, 中央电视台和北京电视台就是观察者. 当北京的天气搜集到新数据的时候, 告诉他们类似的, LiveData<Weather> 就是北京天气, CCTV / BTV, 就是观察者.
LiveData<Weather>.observe(CCTV)
/LiveData<Weather>.observe(BTV)
就是把 CCTV 和 BTV 加到了 Weather 的观察者列表中
当调用了 LiveData<Weather>.set(newWeather) 之后, 通知 CCTV 和 BTV, 告诉他们最新的天气情况.
可以看出, LiveData 本身不存数据, 数据是存在 weather 中
也可以看出, LiveData 中有一个观察者列表 (比如一个 list? 猜测 不知道)
还可以看出, 对 LiveData set 了新的数值之后, 会改变 weather 的数据, 然后通知观察者列表中所有的对象, 调用他们的方法, 把最新的 weather 传递过去对, 这就是 LiveData 了!
-
-
LiveData 怎么用?
作为 ViewModel 的成员变量来用. 先不看代码, 先想一下他可能会是什么样的
比如 我们有一个 Weather 对象, 想在 weather 发生改变的时候, 让 Activity 刷新数据.
那么我们就可以创建一个 WeatherViewModel
在这个 ViewModel 中创建一个 LiveData<Weather> weatherData
然后在 WeatherActivity 中用 weatherViewModel.weatherData.observe(传入一个 Observer接口对象)
这样, 在weatherData 发生了改变之后, 就会调用到Activity 中 Observer接口对象的方法还挺简单的对吧
-
Google 希望我们怎么用?
- 因为在 WeatherActivity 中, 我们只希望他读取 weather, 而不希望他为 weather 设定新的值.
- 所以我们要把 LiveData<Weather> weatherData 这个变成一个对 WeatherActivity 只读的对象
- Google 推荐的方式是一种叫做 Backing Property 的 Kotlin 技术
- 这个方式很简单也很容易理解
- 在 ViewModel 中维护一个 private val
MutableLiveData<Weather>
, MutableLiveData 是一个可改变值的 LiveData. 但由于他是 private 的,所以只有在 ViewModel 内部可以访问到他. - 然后在 weather Activity 中不会直接用到这个
MutableLiveData
- 而是在 ViewModel 中跟private val MutableLiveData<Weather> 一起创建一个: val LiveData<Weather>. 并提供一个 get 方法, 返回MutableLiveData 的值, 代码看起来就是这样的:
class WeatherViewModel: ViewModel() {
private val _weatherData = MutableLiveData<Weather>()
val weatherData: LiveData<Weather>
get() = _weatherData
}
这样的话, 在 Weather Activity 中访问 weatherViewModel.weatherData 就行了. 同时因为 weatherData 他是 val 修饰符, 所以天然不可更改
这样的话, 在 weatherActivity 中, 用 weatherViewModel.weatherData.observe(observer 的接口实现) 就可以实现对 livedata 数据的监听了.
-
LiveData V.S. Presenter
我们都听说过 MVP 和 MVVM
乍一看, 感觉 P(resenter)应该跟 ViewModel 对应啊!
不错, 但其实我感觉, P应该跟 VM + LiveData 对应
我们可以用 Activity 中像调用 Presenter 的方法一样去调用 VM 的方法, 此时他们仅仅是一个名字的区别而已对吧!
但是别忘了. 在 Presenter 中虽然我们没有直接持有对 view 的引用, 但是我们的 P持有了一个view 接口的引用, 从而可以在数据发生变化的时候, 调用这个接口的方法, 最终传递给真正的 view , 使其发生改变.
但是, 如果我们让 ViewModel 也持有对 view 的引用(这是 Google 明令禁止的!), 那岂不是跟 MVP 没有任何区别了.
是的, 那怎么解决将数据回传到 Activity 来更新 view 呢?
答案就是 LiveData, LiveData 的观察者模式, 使其可以在数据发生改变时把最新的数据传递给所有的观察者对象.
如果这个观察者对象在 Activity 中, 那么他就把数据传递给了 Activity.
~另外! LiveData 是可以感知观察者的生命周期的, 也就是说 Activity 在停止或销毁的状态时, 是不会调用其中的观察者的回调方法的. 这样, 我们在数据发生改变之后就不用检测 Activity 是不是活动状态了, 岂不是有点爽?!