LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.
LiveData是一個可觀察的數(shù)據(jù)持有類。和普通的可觀察對象不同,LiveData具有生命周期感知性——即是說,它會遵循其他應(yīng)用組件(如Activity、Fragment、Service)的生命周期。這保證了LiveData只會在這些組件活動的時候才去更新它們。
也就是說,LiveData實質(zhì)上是一個被觀察者,而Activity/Fragment等,則是作為觀察者。每當(dāng)LiveData所持有的數(shù)據(jù)發(fā)生改變,LiveData都會通知觀察者,從而進(jìn)行更新UI等操作——這跟RxJava的觀察者模式是類似的。
1. LiveData的工作流程
1.1 創(chuàng)建一個LiveData對象。這通常是在ViewModel中進(jìn)行的。
1.2 創(chuàng)建一個Observer,并實現(xiàn)onChanged()方法。onChanged()方法決定了當(dāng)數(shù)據(jù)發(fā)生改變的時候需要做的操作,比如更新UI等。
1.3 通過LiveData的observe方法將其和Observer綁定。
當(dāng)LiveData的數(shù)據(jù)發(fā)生更新時,他會通過setValue(T)/postValue(T)通知所有和他綁定的并且處于活動狀態(tài)的觀察者。
注意:
- LiveData對象應(yīng)該保存在ViewModel中而不是Activity/Fragment。
- setValue方法必須在主線程調(diào)用。如果在子線程,使用postValue方法。
2. 繼承LiveData
當(dāng)一個觀察者的狀態(tài)是Lyfecycle.State.STARTED或者Lyfecycle.State.RESUMED的時候,它被認(rèn)為是活動狀態(tài)的。當(dāng)與LiveData綁定的活動Observer數(shù)量從0變?yōu)?,則會調(diào)用它的onActive()回調(diào);反之,onInactive()回調(diào)被調(diào)用。
class UserLiveData(val id: String) : LiveData<UserProfile>() {
private val userManager = UserManager()
override fun onActive() {
userManager.getUserProfile(id, object : Callback<UserProfile> {
override fun onFailure(call: Call<UserProfile>, t: Throwable) {
t.printStackTrace()
}
override fun onResponse(call: Call<UserProfile>, response: Response<UserProfile>) {
postValue(response.body())
}
})
}
}
3. 轉(zhuǎn)換LiveData
通過Transformations類來轉(zhuǎn)換LiveData的類型:
val userLiveData: LiveData<UserProfile> = UserLiveData(id)
val userName : LiveData<String> = Transformations.map(userLiveData) {
user -> user.username
}
4. 使用LiveData類
因為LiveData的setValue/postValue方法不是public的,所以一般在使用LiveData的時候,會建立一個繼承自LiveData的子類,或者直接使用MutableLiveData類。
例如,每隔一秒更新一個TextView的內(nèi)容,可以這么寫:
// 繼承方式
fun subscribeUI() {
val liveData = CountLiveData()
liveData.observe(viewLifecycleOwner, Observer<String> { countStr ->
textView.text = countStr
})
}
class CountLiveData : LiveData<String>() {
private var count = 0
private val timer: Timer = Timer()
private val task = timerTask {
count++
postValue(count.toString())
}
override fun onActive() {
timer.schedule(task, 1000, 1000)
}
}
也可以直接這么寫:
// MutableLiveData方式
var count = 0
val liveData = MutableLiveData<String>()
fun subscribeUI() {
val timer = Timer()
val timerTask = timerTask {
count++
liveData.postValue(count.toString())
}
timer.schedule(timerTask, 1000, 1000)
liveData.observe(viewLifecycleOwner, Observer<String> { countStr ->
textView.text = countStr
})
}