Android架構(gòu)組件LiveData使用詳解
LiveData
LiveData是基于觀察者模式創(chuàng)建的,其中,LiveData是被觀察者,觀察者通過注冊方法,監(jiān)聽被觀察者的數(shù)據(jù)變化。LiveData在數(shù)據(jù)發(fā)生變化的時候,會通知觀察者。
LiveData是一個容器,存放數(shù)據(jù)的容器,它的數(shù)據(jù)變化可以被監(jiān)聽,也就是LiveData是一個被觀察者,如下,創(chuàng)建了一個存放String的數(shù)據(jù)容器currentName:
public class NameViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> currentName;
? ?public MutableLiveData<String> getCurrentName() {
? ? ? ?if (currentName == null) {
? ? ? ? ? ?currentName = new MutableLiveData<String>();
? ? ? ?}
? ? ? ?return currentName;
? ?}
// Rest of the ViewModel...
}監(jiān)聽LiveData數(shù)據(jù)變化,為LiveData添加觀察者,如下,添加一個nameObserver,監(jiān)聽LiveData的數(shù)據(jù)變化,當(dāng)LiveData的數(shù)據(jù)發(fā)生變化的的時候,onChanged方法會被回調(diào),從而更新UI。
public class NameActivity extends AppCompatActivity {
? ?private NameViewModel model;
? ?@Override
? ?protected void onCreate(Bundle savedInstanceState) {
? ? ? ?super.onCreate(savedInstanceState);
? ? ? ?// Other code to setup the activity...
? ? ? ?// Get the ViewModel.
? ? ? ?model = new ViewModelProvider(this).get(NameViewModel.class);
? ? ? ?// Create the observer which updates the UI.
? ? ? ?final Observer<String> nameObserver = new Observer<String>() {
? ? ? ? ? ?@Override
? ? ? ? ? ?public void onChanged(@Nullable final String newName) {
? ? ? ? ? ? ? ?// Update the UI, in this case, a TextView.
? ? ? ? ? ? ? ?nameTextView.setText(newName);
? ? ? ? ? ?}
? ? ? ?};
? ? ? ?// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
? ? ? ?model.getCurrentName().observe(this, nameObserver);
? ?}
}更新LiveData數(shù)據(jù)的方式,使用setValue和postValue兩個方法
LiveData發(fā)布修改有setValue和postValue兩種方式,其中setValue只能在主線程調(diào)用,postValue則沒有這個限制
button.setOnClickListener(new OnClickListener() {
? ?@Override
? ?public void onClick(View v) {
? ? ? ?String anotherName = "John Doe";
? ? ? ?model.getCurrentName().setValue(anotherName);
? ?}
});應(yīng)用架構(gòu)中的LiveData
LiveData 具有生命周期感知能力,遵循 activity 和 fragment 等實(shí)體的生命周期。您可以使用 LiveData 在這些生命周期所有者和生命周期不同的其他對象(例如 ViewModel 對象)之間傳遞數(shù)據(jù)。ViewModel 的主要責(zé)任是加載和管理與界面相關(guān)的數(shù)據(jù),因此非常適合作為用于保留 LiveData 對象的備選方法。您可以在 ViewModel 中創(chuàng)建 LiveData 對象,然后使用這些對象向界面層公開狀態(tài)。
activity 和 fragment 不應(yīng)保留 LiveData 實(shí)例,因?yàn)樗鼈兊挠猛臼秋@示數(shù)據(jù),而不是保持狀態(tài)。此外,如果 activity 和 fragment 無需保留數(shù)據(jù),還可以簡化單元測試的編寫。
擴(kuò)展LiveData
如果觀察者的生命周期處于 STARTED 或 RESUMED 狀態(tài),LiveData 會認(rèn)為該觀察者處于活躍狀態(tài)。以下示例代碼說明了如何擴(kuò)展 LiveData 類
public class StockLiveData extends LiveData<BigDecimal> {
????private StockManager stockManager;
????private SimplePriceListener listener = new SimplePriceListener() {
????????@Override
????????public void onPriceChanged(BigDecimal price) {
????????????setValue(price);
????????}
????};
????public StockLiveData(String symbol) {
????????stockManager = new StockManager(symbol);
????}
????@Override
????protected void onActive() {
????????stockManager.requestPriceUpdates(listener);
????}
????@Override
????protected void onInactive() {
????????stockManager.removeUpdates(listener);
????}
}當(dāng)LiveData對象具有活躍觀察者時, 會調(diào)用 onActive() 方法。這意味著,您需要從此方法開始觀察股價更新。
當(dāng) LiveData 對象沒有任何活躍觀察者時,會調(diào)用 onInactive() 方法。由于沒有觀察者在監(jiān)聽,因此沒有理由與 StockManager 服務(wù)保持連接。
setValue(T) 方法將更新 LiveData 實(shí)例的值,并將更改告知活躍觀察者。
LiveData使用總結(jié)
創(chuàng)建LiveData,使用viewModel類來包含
創(chuàng)建觀察者Observer
調(diào)用LiveData的observe方法將LiveData以及Observer建立起發(fā)布-訂閱關(guān)系
在適當(dāng)?shù)臅r機(jī)調(diào)用LiveData的setValue或者postValue發(fā)布新數(shù)據(jù)通知觀察者
LiveData的優(yōu)點(diǎn)
能夠確保數(shù)據(jù)和UI統(tǒng)一
LiveData采用了觀察者模式,當(dāng)數(shù)據(jù)發(fā)生變化時,主動通知被觀察者。
解決內(nèi)存泄露問題
由于LiveData會在Activity/Fragment等具有生命周期的lifecycleOwner組件調(diào)用onDestory的時候自動解綁,所以解決了可能存在的內(nèi)存泄漏問題。之前我們?yōu)榱吮苊膺@個問題,一般有注冊綁定的地方都要解綁(即注冊跟解綁要成對出現(xiàn)),而LiveData利用生命周期感知功能解決了這一問題,可以實(shí)現(xiàn)只需關(guān)心注冊,而解綁會根據(jù)生命周期自動進(jìn)行的功能。
當(dāng)Activity停止時不會引起崩潰
當(dāng)Activity組件處于inactive非活動狀態(tài)時,它不會收到LiveData數(shù)據(jù)變化的通知。
不需要手動處理生命周期的變化
觀察者并不需要手動處理生命周期變化對自身的邏輯的影響,只需要關(guān)心如何處理獲取到的數(shù)據(jù)。LiveData能夠感知Activity/Fragment等組件的生命周期變化,所以就完全不需要在代碼中告訴LiveData組件的生命周期狀態(tài),當(dāng)數(shù)據(jù)發(fā)生變化時,只在生命周期處于active下通知觀察者,而在inactive下,不會通知觀察者。
確??偰塬@取到最新的數(shù)據(jù)
什么意思呢?第一種情況,當(dāng)觀察者處于active活動狀態(tài)。LiveData基于觀察者模式,所以當(dāng)數(shù)據(jù)發(fā)生變化,觀察者能夠馬上獲取到最新變化;第二種情況,當(dāng)觀察者處于inactive非活動狀態(tài)。LiveData只能生命周期active下發(fā)送數(shù)據(jù)給觀察者。舉個例子,當(dāng)Activity處于后臺(inactive)時,LiveData接收到了新的數(shù)據(jù),但這時候LiveData并不會通知該Activity,但是當(dāng)該Activity重新返回前臺(active)時會繼續(xù)接收到最新的數(shù)據(jù)。一句話概括,LiveData是粘性的。
configuration changes時,不需要額外的處理來保存數(shù)據(jù)我們知道,當(dāng)你把數(shù)據(jù)存儲在組件中時,當(dāng)configuration change(比如語言、屏幕方向變化)時,組件會被recreate,然而系統(tǒng)并不能保證你的數(shù)據(jù)能夠被恢復(fù)的。當(dāng)我們采用LiveData保存數(shù)據(jù)時,因?yàn)閿?shù)據(jù)和組件分離了。當(dāng)組件被recreate,數(shù)據(jù)還是存在LiveData中,并不會被銷毀。
資源共享
通過繼承LiveData類,然后將該類定義成單例模式,在該類封裝監(jiān)聽一些系統(tǒng)屬性變化,然后通知LiveData的觀察者。
LiveData源碼分析:
public interface Observer<T> {
??/**
???* Called when the data is changed.
???* @param t??The new data
???*/
??void onChanged(@Nullable T t);
}
// 注意,他是 abstract class
public abstract class LiveData<T> {
??// 只有 onStart 后,對數(shù)據(jù)的修改才會觸發(fā) observer.onChanged()
??public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {}
??// 無論何時,只要數(shù)據(jù)發(fā)生改變,就會觸發(fā) observer.onChanged()
??public void observeForever(@NonNull Observer<T> observer) {}
}到此這篇關(guān)于Android架構(gòu)組件LiveData使用詳解的文章就介紹到這了,更多相關(guān)Android架構(gòu)組件LiveData內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android Jetpack架構(gòu)組件Lifecycle詳解
- Android Jetpack架構(gòu)組件 ViewModel詳解
- Android 生命周期架構(gòu)組件使用方法
- Android架構(gòu)組件Room的使用詳解
- Android架構(gòu)組件Room指南
- Android-ViewModel和LiveData使用詳解
- Android LiveData使用需要注意的地方
- Android mvvm之LiveData原理案例詳解
- Android 基于MediatorLiveData實(shí)現(xiàn)紅點(diǎn)的統(tǒng)一管理
- 詳解Android JetPack之LiveData的工作原理
相關(guān)文章
Android Flutter實(shí)現(xiàn)彈幕效果
這篇文章主要為大家詳細(xì)介紹如何利用Android FLutter實(shí)現(xiàn)彈幕效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06
Android實(shí)現(xiàn)自定義驗(yàn)證碼輸入框效果(實(shí)例代碼)
這篇文章主要介紹了Android實(shí)現(xiàn)自定義驗(yàn)證碼輸入框效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01
Android TextView高級顯示技巧實(shí)例小結(jié)
這篇文章主要介紹了Android TextView高級顯示技巧,結(jié)合實(shí)例形式總結(jié)分析了Android TextView控件進(jìn)行文字與圖片顯示的相關(guān)操作技巧,需要的朋友可以參考下2016-10-10
詳解android特性之CoordinatorLayout用法探析實(shí)例
本篇文章主要介紹了android特性之CoordinatorLayout用法探析實(shí)例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02
Android使用ViewDragHelper實(shí)現(xiàn)QQ聊天氣泡拖動效果
這篇文章主要為大家詳細(xì)介紹了Android使用ViewDragHelper實(shí)現(xiàn)QQ聊天氣泡拖動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-01-01
Jetpack?Compose?實(shí)現(xiàn)一個圖片選擇框架功能
這篇文章主要介紹了Jetpack?Compose?實(shí)現(xiàn)一個圖片選擇框架,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06

