LiveData
編寫說明,文章收錄于《Android Jetpack》,文章將大部分摘錄于
[官方教程][https://developer.android.google.cn/topic/libraries/architecture/livedata
]
1.核心功能
LiveData 是一種可觀察的數(shù)據(jù)存儲器類。與常規(guī)的可觀察類不同,LiveData 具有生命周期感知能力,意指它遵循其他應用組件(如 Activity、Fragment 或 Service)的生命周期。這種感知能力可確保 LiveData 僅更新處于活躍生命周期狀態(tài)的應用組件觀察者。
如果觀察者(由 Observer 類表示)的生命周期處于 STARTED 或 RESUMED 狀態(tài),則 LiveData 會認為該觀察者處于活躍狀態(tài)。LiveData 只會將更新通知給活躍的觀察者。為觀察 LiveData 對象而注冊的非活躍觀察者不會收到更改通知。
您可以注冊與實現(xiàn) LifecycleOwner 接口的對象配對的觀察者。有了這種關系,當相應的 Lifecycle 對象的狀態(tài)變?yōu)?DESTROYED 時,便可移除此觀察者。 這對于 Activity 和 Fragment 特別有用,因為它們可以放心地觀察 LiveData 對象而不必擔心泄露(當 Activity 和 Fragment 的生命周期被銷毀時,系統(tǒng)會立即退訂它們)。
2.使用 LiveData 的優(yōu)勢
確保界面符合數(shù)據(jù)狀態(tài)
LiveData 遵循觀察者模式。當生命周期狀態(tài)發(fā)生變化時,LiveData 會通知Observer對象。您可以整合代碼以在這些Observer對象中更新界面。觀察者可以在每次發(fā)生更改時更新界面,而不是在每次應用數(shù)據(jù)發(fā)生更改時更新界面。不會發(fā)生內存泄漏
觀察者會綁定到Lifecycle對象,并在其關聯(lián)的生命周期遭到銷毀后進行自我清理。不會因 Activity 停止而導致崩潰
界面組件只是觀察相關數(shù)據(jù),不會停止或恢復觀察。LiveData 將自動管理所有這些操作,因為它在觀察時可以感知相關的生命周期狀態(tài)變化。數(shù)據(jù)始終保持最新狀態(tài)
如果生命周期變?yōu)榉腔钴S狀態(tài),它會在再次變?yōu)榛钴S狀態(tài)時接收最新的數(shù)據(jù)。例如,曾經(jīng)在后臺的 Activity 會在返回前臺后立即接收最新的數(shù)據(jù)。適當?shù)呐渲酶?br> 如果由于配置更改(如設備旋轉)而重新創(chuàng)建了 Activity 或 Fragment,它會立即接收最新的可用數(shù)據(jù)。
共享資源
您可以使用單一實例模式擴展LiveData對象以封裝系統(tǒng)服務,以便在應用中共享它們。LiveData對象連接到系統(tǒng)服務一次,然后需要相應資源的任何觀察者只需觀察LiveData對象。如需了解詳情,請參閱擴展 LiveData。
3.使用 LiveData 對象
- 創(chuàng)建
LiveData實例以存儲某種類型的數(shù)據(jù)。這通常在ViewModel類中完成 - 創(chuàng)建可定義
onChanged()方法的Observer對象,該方法可以控制當LiveData對象存儲的數(shù)據(jù)更改時會發(fā)生什么。通常情況下,您可以在界面控制器(如 Activity 或 Fragment)中創(chuàng)建Observer對象。
- 使用
observe()方法將Observer對象附加到LiveData對象。observe()方法會采用LifecycleOwner對象。這樣會使Observer對象訂閱LiveData對象,以使其收到有關更改的通知。通常情況下,您可以在界面控制器(如 Activity 或 Fragment)中附加Observer對象。
當您更新存儲在 LiveData 對象中的值時,它會觸發(fā)所有已注冊的觀察者(只要附加的 LifecycleOwner 處于活躍狀態(tài))。
LiveData 允許界面控制器觀察者訂閱更新。當 LiveData 對象存儲的數(shù)據(jù)發(fā)生更改時,界面會自動更新以做出響應。
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...
}
注意:請確保用于更新界面的 LiveData 對象存儲在 ViewModel 對象中,而不是將其存儲在 Activity 或 Fragment 中,原因如下:
- 避免 Activity 和 Fragment 過于龐大?,F(xiàn)在,這些界面控制器負責顯示數(shù)據(jù),但不負責存儲數(shù)據(jù)狀態(tài)
- 將 LiveData 實例與特定的 Activity 或 Fragment 實例分離開,并使 LiveData 對象在配置更改后繼續(xù)存在。
4.觀察 LiveData 對象
確保系統(tǒng)不會從 Activity 或 Fragment 的
[onResume()](https://developer.android.google.cn/reference/android/app/Activity#onResume())方法進行冗余調用。-
確保 Activity 或 Fragment 變?yōu)榛钴S狀態(tài)后具有可以立即顯示的數(shù)據(jù)。一旦應用組件處于
STARTED狀態(tài),就會從它正在觀察的LiveData對象接收最新值。只有在設置了要觀察的LiveData對象時,才會發(fā)生這種情況。
通常,LiveData 僅在數(shù)據(jù)發(fā)生更改時才發(fā)送更新,并且僅發(fā)送給活躍觀察者。此行為的一種例外情況是,觀察者從非活躍狀態(tài)更改為活躍狀態(tài)時也會收到更新。此外,如果觀察者第二次從非活躍狀態(tài)更改為活躍狀態(tài),則只有在自上次變?yōu)榛钴S狀態(tài)以來值發(fā)生了更改時,它才會收到更新。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); }}
5.更新 LiveData 對象
LiveData 沒有公開可用的方法來更新存儲的數(shù)據(jù)。MutableLiveData 類將公開 setValue(T) 和 postValue(T) 方法,如果您需要修改存儲在 LiveData 對象中的值,則必須使用這些方法。通常情況下會在 ViewModel 中使用 MutableLiveData,然后 ViewModel 只會向觀察者公開不可變的 LiveData 對象。
設置觀察者關系后,您可以更新 LiveData 對象的值(如以下示例中所示),這樣當用戶點按某個按鈕時會觸發(fā)所有觀察者:
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String anotherName = "John Doe";
model.getCurrentName().setValue(anotherName);
}
});
在本例中調用 `setValue(T)` 導致觀察者使用值 `John Doe` 調用其 [`onChanged()`](https://developer.android.google.cn/reference/androidx/lifecycle/Observer#onChanged(T)) 方法。本例中演示的是按下按鈕的方法,但也可以出于各種各樣的原因調用 `setValue()` 或 `postValue()` 來更新 `mName`,這些原因包括響應網(wǎng)絡請求或數(shù)據(jù)庫加載完成。在所有情況下,調用 `setValue()` 或 `postValue()` 都會觸發(fā)觀察者并更新界面。
注意:您必須調用 setValue(T) 方法以從主線程更新 LiveData 對象。如果在 worker 線程中執(zhí)行代碼,則您可以改用 postValue(T) 方法來更新 LiveData 對象。