Android LiveData使用
LiveData是一個(gè)可觀察的數(shù)據(jù)持有者類。 與常規(guī)observable不同,LiveData是生命周期感知的,當(dāng)生命周期處于STARTED或RESUMED狀態(tài),則LiveData會(huì)將其視為活動(dòng)狀態(tài),這意味著它尊重其他應(yīng)用程序組件的生命周期,例如Activity,F(xiàn)ragment或Service。
LiveData具有以下優(yōu)點(diǎn):
UI和數(shù)據(jù)保持一致:遵循觀察者模式,生命周期狀態(tài)更改時(shí),LiveData會(huì)通知Observer對(duì)象
避免內(nèi)存泄漏:觀察者綁定到Lifecycle對(duì)象,并在其相關(guān)生命周期被破壞后自行清理
不會(huì)因stop而崩潰:處于非活動(dòng)狀態(tài),不會(huì)接收到LiveData事件,如Activity變?yōu)椴豢梢?br />
自動(dòng)感知生命周期:LiveData自動(dòng)管理在觀察時(shí)意識(shí)到相關(guān)的生命周期狀態(tài)變化。
數(shù)據(jù)始終保持最新:生命周期變?yōu)榉腔顒?dòng)狀態(tài)再次變?yōu)榛顒?dòng)狀態(tài)時(shí)接收最新數(shù)據(jù)。 例如,Activity不可見變?yōu)榭梢姇r(shí)立即接收最新數(shù)據(jù)
解決Configuration changes問題:當(dāng)屏幕旋轉(zhuǎn)或者回收時(shí),重新創(chuàng)建Activity或Fragment,可以即時(shí)收到數(shù)據(jù)變更
共享資源:使用單例擴(kuò)展LiveData,就可在app中共享它
gradle配置
def lifecycle_version = "2.0.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
創(chuàng)建LiveData對(duì)象
class TestViewModel : ViewModel() {
private lateinit var userName: MutableLiveData<String>
fun getUserName(): MutableLiveData<String> {
if (!::userName.isInitialized) {
userName = MutableLiveData()
loadUsers()
}
return userName
}
private fun loadUsers() {
userName.value = "test"
}
}
觀察和變更LiveData對(duì)象
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var model = ViewModelProviders.of(this).get(TestViewModel::class.java)
model.getUserName().observe(this, Observer {
txt_test.text = it
})// 觀察
btn_test.setOnClickListener {
model.getUserName().value = "test 2"
}// 變更
}
}
在變更數(shù)據(jù)的使用有兩種方式可用,一個(gè)是setValue,另外一個(gè)是postValue,區(qū)別是setValue只能在主線程處理,postValue可以在子線程處理。
LiveData結(jié)合Databinding使用
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
var model = ViewModelProviders.of(this).get(TestViewModel::class.java)
binding.let {
it.data = model
it.setLifecycleOwner(this)
}
btn_test.setOnClickListener {
model.getUserName().value = "test 2"
}
}
}
binding對(duì)象需要調(diào)用setLifecycleOwner(LifecycleOwner lifecycleOwner)設(shè)置lifecycleOwner對(duì)象。
擴(kuò)展LiveData
通常LiveData只關(guān)心觀察者的STARTED或RESUMED狀態(tài),下面代碼片段擴(kuò)展了LiveData
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
private var mStockManager: StockManager? = null
private val mListener = object : SimplePriceListener() {
fun onPriceChanged(price: BigDecimal) {
value = price
}
}
init {
mStockManager = StockManager(symbol)
}
override fun onActive() {
mStockManager.requestPriceUpdates(mListener)
}
override fun onInactive() {
mStockManager.removeUpdates(mListener)
}
}
實(shí)現(xiàn)包括以下重要方法:
當(dāng)?LiveData?對(duì)象具有活躍觀察者時(shí),會(huì)調(diào)用?onActive()?方法。這意味著,您需要從此方法開始觀察數(shù)據(jù)更新。
當(dāng)?LiveData?對(duì)象沒有任何活躍觀察者時(shí),會(huì)調(diào)用?onInactive()?方法。由于沒有觀察者在監(jiān)聽,因此沒有理由與?StockManager?服務(wù)保持連接。
setValue(T)?方法將更新?LiveData?實(shí)例的值,并將更改通知給任何活躍觀察者。
使用擴(kuò)展LiveData
class TestFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val stockLiveData = StockLiveData("")
stockLiveData.observe(this, Observer {
// update UI
})
}
}
observe()?方法將傳遞 Fragment(它是?LifecycleOwner?的實(shí)例)作為第一個(gè)參數(shù)。這樣做表示此觀察者綁定到與所有者關(guān)聯(lián)的?Lifecycle?對(duì)象,這意味著:
如果?Lifecycle?對(duì)象未處于活躍狀態(tài),那么即使值發(fā)生更改,也不會(huì)調(diào)用觀察者。
銷毀?Lifecycle?對(duì)象后,會(huì)自動(dòng)移除觀察者
當(dāng)然可以在多個(gè) Activity、Fragment 和 Service 之間共享它們,只需要把 StockLiveData類實(shí)現(xiàn)為單例。
轉(zhuǎn)換 LiveData
LiveData?對(duì)象分派給觀察者之前對(duì)存儲(chǔ)在其中的值進(jìn)行更改,或者您可能需要根據(jù)另一個(gè)實(shí)例的值返回不同的?LiveData?實(shí)例。其提供了以下方法進(jìn)行轉(zhuǎn)換
Transformations.map()
LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
? ? user.name + " " + user.lastName
});
Transformations.switchMap()
LiveData<String> userId = ...;
LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );
要實(shí)現(xiàn)您自己的轉(zhuǎn)換,可以使用?MediatorLiveData?類,該類可以監(jiān)聽其他?LiveData?對(duì)象并處理它們發(fā)出的事件,其可以正確地將其狀態(tài)傳播到源?LiveData?對(duì)象。
總結(jié)
以上是生活随笔為你收集整理的Android LiveData使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何修改 pdf 文件默认的显示图标
- 下一篇: Python 读取 pkl文件