LiveData
LiveData
是一种可观察的数据存储器类。与常规的可观察类不同,它具有生命周期感知能力,意指它遵循其他应用组件(如Activity
、Fragment
或Service
等)的生命周期。这种感知能力可确保LiveData
仅更新处于活跃生命周期状态的应用组件观察者。
特点
合理的使用LiveData
能具有以下优点:
- 能够保证数据和UI统一。由于
LiveData
采用了观察者模式有关,LiveData是被观察者,当数据有变化时会通知观察者(UI)。 - 减少内存泄漏。由于
LiveData
能够感知到组件的生命周期,当组件处于DESTROYED
状态时,观察者对象会被清除掉。 - 当Activity停止时不会引起崩溃。这是因为组件处于非激活状态时,不会收到LiveData中数据变化的通知。
- 不需要额外的手动处理来响应生命周期的变化。 这一点同样是因为LiveData能够感知组件的生命周期,所以就完全不需要在代码中告诉LiveData组件的生命周期状态。
- 组件和数据相关的内容能实时更新。组件在前台的时候能够实时收到数据改变的通知,这是可以理解的。当组件从后台到前台来时,LiveData能够将最新的数据通知组件,这两点就保证了组件中和数据相关的内容能够实时更新。
- 针对
configuration change
时,不需要额外的处理来保存数据。我们知道,当你把数据存储在组件中时,当configuration change
(比如语言、屏幕方向变化)时,组件会被recreate
,然而系统并不能保证你的数据能够被恢复的。当我们采用LiveData
保存数据时,因为数据和组件分离了。当组件被recreate
,数据还是存在LiveData
中,并不会被销毁。 - 资源共享。通过继承
LiveData
类,然后将该类定义成单例模式,在该类封装监听一些系统属性变化,然后通知LiveData
的观察者。
使用
可以直接使用LiveData<T>
对象或继承它。
直接使用
//用来设置值
private val testLive: MutableLiveData<String> = MutableLiveData()
//用来和UI绑定时获取值
val mTestLiveData: LiveData<String>
get() = testLive
fun fetchData() {
testLive.value = "fetchData"
}
继承使用
class WiFiStateLiveData private constructor(context: Context) : LiveData<Int>() {
private val mContextWeakReference: WeakReference<Context> = WeakReference(context)
//第一次被观察时,注册广播
override fun onActive() {
super.onActive()
registerReceiver()
}
//没有观察者时,注销广播
override fun onInactive() {
super.onInactive()
unregisterReceiver()
}
private fun registerReceiver() {
val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION)
mContextWeakReference.get()?.registerReceiver(mReceiver, intentFilter)
}
private fun unregisterReceiver() {
mContextWeakReference.get()?.unregisterReceiver(mReceiver)
}
private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
val action = intent.action
Log.d(TAG, "action = $action")
if (WifiManager.RSSI_CHANGED_ACTION == action) {
val wifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200)
val wifiLevel = WifiManager.calculateSignalLevel(
wifiRssi, 4)
// 设置wifi的信号强度等级;如果不在主线程需要调用 sData?.postValue
sData?.value = wifiLevel
}
}
}
companion object {
private const val TAG = "MyLiveData"
private var sData: WiFiStateLiveData? = null
fun getInstance(context: Context): WiFiStateLiveData? {
if (sData == null) {
sData = WiFiStateLiveData(context)
}
return sData
}
}
}
添加观察者
有两种添加观察者的方法:
observeForever()
,通过observeForever()添加观察者,观察者会一直受到数据的变化回调(直到调用removeObserver()
),而不是在组件处于STARTED
和RESUMED
状态下才会收到。
observe()
,在组件处于STARTED
和RESUMED
状态下才会收到数据的变化回调。
注意
:一旦观察者被添加就会收到当前LiveData
的值。