簡體   English   中英

即使數據沒有變化,LiveData 觀察者的 onChanged 也會在活動輪換時被調用

[英]LiveData observer's onChanged gets called on activity rotation even though there was no change in the data

我正在 Android 應用程序中使用ViewModelsLiveData ,即使屏幕旋轉,我也想使用它們來跟蹤 Activity 的數據。 這工作得很好,但有一個問題我無法解決。 在 Activity 的onCreate方法中,我為包含對象列表的 LiveData 注冊了一個觀察者,如果加載了數據,它應該只向 Activity 添加一個 Fragment。 然后,我只在savedInstanceState為 null 時重新加載數據,這應該會在屏幕旋轉時阻止它重新加載。 這看起來像這樣:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        model = ViewModelProviders.of(this).get(MainActivityModel.class);
        observeList();
        if (savedInstanceState == null) {
            loadList(); //Reload the list and call postValue() on the LiveData.
        }
    }

    private void observeList() {
        model.getList().observe(this, new Observer<ArrayList<Object>>(){
            @Override
            public void onChanged(@Nullable ArrayList<Object> objects) {
                //Add list fragment whenever data changes.
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.container, ListFragment.getInstance(list))
                        .commit();
            }
        });
    }

我理解它的方式, ListFragment 應該只在數據更改時顯示。 但是,經過一些調試,每次屏幕旋轉時,observeList 方法中的onChanged方法似乎都會被調用。 此外,我檢查了實際列表是否已更改並且完全相同,完全沒有區別,甚至從未調用過postValue( ) 或setValue()方法。 因此,我不知道為什么會在屏幕旋轉時調用 onChanged 方法。

這也僅在列表包含某些內容時發生。 當應用程序啟動時,在調用loadList()之前列表的長度為 0。 當觀察者在這個 state 注冊時,不會調用 onChanged 方法。

我最好的猜測是onChanged方法被觸發是因為當觀察者注冊時列表不是空的,所以觀察者可能認為數據發生了變化。 誰能解釋為什么會發生這種情況?

這是按預期工作的。 實時數據概述

確保活動或片段具有可在其變為活動狀態后立即顯示的數據。 一旦應用程序組件處於 STARTED 狀態,它就會從它正在觀察的 LiveData 對象接收最新的值。 只有在設置了要觀察的 LiveData 對象時才會發生這種情況。

盡管缺少代碼片段 - loadList應該是 ViewModel 本身的一部分,而不是一種活動方法。

我遇到了同樣的問題,並在此代碼實驗室中找到了解決方案: Training LiveData

通常,LiveData 僅在數據更改時才向觀察者提供更新。 這種行為的一個例外是,當觀察者從非活動狀態變為活動狀態時,觀察者也會收到更新。

當 (...) 片段在屏幕旋轉后重新創建時,它會從非活動狀態變為活動狀態。 片段中的觀察者重新連接到現有的 ViewModel 並接收當前數據。

所以解決方案基本上是在視圖模型中創建一些方法來重置觸發觀察者的變量的值(在你的情況下,列表)。

當屏幕旋轉時,會調用 Activity 生命周期中的以下回調方法

  1. onSaveInstanceState()
  2. 暫停()
  3. 停止()
  4. onCreate()
  5. 開始()
  6. onRestoreInstanceState()
  7. onResume()

如果您記住實時數據觀察器是生命周期感知的,這將有所幫助,這意味着它會在 UI 處於活動 state 時進行觀察,並在 UI 不在活動 state 時停止觀察。 當調用 onStop 方法時,實時數據觀察者停止偵聽,當再次調用 onCreate 方法時,實時數據觀察者再次開始觀察。 這就是重新加載觀察者的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM