1、LiveData 概览 Android Jetpack 的一部分。
LiveData
是一种可观察的数据存储容器类。与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他组件(activity、fragment、service)的生命周期。这种感知生命周期的能力可确保LiveData更新生命周期处于活跃的应用组件观察者。
如果观察者(Observer)处于STARTED或RESUMED的状态,则LiveData会认为该观察者处于活跃状态,LiveData只会将更新通知发送活跃状态的观察者,为观察LiveData而处于不活跃状态的观察者不会接收到更新通知。
您可以注册与实现 LifecycleOwner
接口的对象配对的观察者。有了这种关系,当相应的 Lifecycle
对象的状态变为 DESTROYED
时,便可移除此观察者。这对于 Activity 和 Fragment 特别有用,因为它们可以放心地观察 LiveData
对象,而不必担心泄露(当 Activity 和 Fragment 的生命周期被销毁时,系统会立即退订它们)。
以上为官网解释,可理解为:
1、LiveData是一种可观察数据存储容器类
2、LiveData可感知组件生命周期
3、LiveData只会通知更新处于生命周期活跃(STARTED、 RESUMED)的应用组件,非活跃状态的组件不通知更新。
4、……?
2、使用 LiveData 的优势
2.1、确保界面符合数据状态
:LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer
对象。您可以整合代码以在这些 Observer
对象中更新界面。这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。
2.2、 不会发生内存泄漏
:观察者会绑定到 Lifecycle
对象,并在其关联的生命周期遭到销毁后进行自我清理。
2.3、不会因 Activity 停止而导致崩溃
:如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
2.4、不再需要手动处理生命周期
:界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
2.5、数据始终保持最新状态
:如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
2.6、适当的配置更改
:如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
2.7、共享资源
:您可以使用单例模式扩展 LiveData
对象以封装系统服务,以便在应用中共享它们。LiveData
对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData
对象。
3、使用LiveData:
class XXXViewModel : ViewModel() {
//TODO:第一步: Create a LiveData with a String
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
//备注:确保将界面刷新的LiveData对象存储在ViewModel中,而不是存储在视图层;
//主要原因是避免视图层过于庞大,现在视图层只负责显示数据,但是不负责存储数据
//将视图层和数据状态层向分离,
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Other code to setup the activity...
// TODO:第二步 Create the observer which updates the UI.
//备注:选择在onCreate中观察,
//原因1:确保系统不会从 Activity 或 Fragment 的 onResume() 方法进冗余调用。
//原因2:确保 Activity 或 Fragment 变为活跃状态后具有可以立即显示的数据。
val nameObserver = Observer<String> { newName ->
// Update the UI, in this case, a TextView.
nameTextView.text = newName
}
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
model.currentName.observe(this, nameObserver)
}
LiveData本身没有公开可更新存储数据的方法,一般我们会在ViewModel内使用LiveData的子类MutableLiveData<T> 进行更新存储的数据
//用于主线程更新数据
mViewModel.currentName.value = "my name is tanker-beta beta"
//用于子线程更新数据
mViewModel.currentName.postValue("my name is asyn tanker")
4、扩展LiveData
/**
* 扩展LiveData,感知应用组件的生命周期,
*/
class StockLiveData(name: String) : LiveData<BigDecimal>() {
private val TAG by lazy {
StockLiveData::class.java.simpleName
}
//TODO: LiveData单例化,共享数据
companion object {
val instances: StockLiveData by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
StockLiveData("beta")
}
}
override fun onActive() {
super.onActive()
//do something onActivity
request.connection()
}
override fun onInactive() {
super.onInactive()
//close something onInactive
request.close() or cancle()
}
}
//TODO:使用
StockLiveData.instances.observe(this){
//update UI
}
5、转换LiveData
//Transformations.map()
//对存储在 LiveData 对象中的值应用函数,并将结果传播到下游。
val realName: LiveData<String> = Transformations.map(currentName) { currentName ->
"$currentName >>>> Transformations.map"
}
//Transformations.switchMap()
//与 map() 类似,对存储在 LiveData 对象中的值应用函数,并将结果解封和分派到下游。
// 传递给 switchMap() 的函数必须返回 LiveData 对象,如以下示例中所示:
val realName2: LiveData<String> = Transformations.switchMap(currentName) { it ->
getRealName2(it)
}
fun getRealName2(msg: String): LiveData<String> {
return MutableLiveData<String>("$msg>>>>>getRealName2.switchMap")
}
备注: 创建新的转换
有十几种不同的特定转换在您的应用中可能很有用,但默认情况下不提供它们。如需实现您自己的转换,您可以使用MediatorLiveData
类,该类可以监听其他LiveData
对象并处理它们发出的事件。MediatorLiveData
正确地将其状态传播到源LiveData
对象。如需详细了解此模式,请参阅Transformations
类的参考文档。
以上为官网基本的LiveData的介绍和使用相关学习记录
下面记录下使用中LiveData遇到的问题和解决方案: