LiveData

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 類表示)的生命周期處于 STARTEDRESUMED 狀態(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 對象。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容