LiveData 觀察測試說明文檔

一、測試概述

本測試旨在驗證在不同 ViewModelStoreOwnerLifecycleOwner 配置下,Activity 和 Fragment 對 LiveData 的觀察行為。

核心概念

  • ViewModelStoreOwner: 決定 ViewModel 實例的存儲位置和共享范圍

    • 使用 Activity 作為 ViewModelStoreOwner:Activity 和所有使用 Activity 的 Fragment 共享同一個 ViewModel 實例
    • 使用 Fragment 作為 ViewModelStoreOwner:每個 Fragment 擁有獨立的 ViewModel 實例
  • LifecycleOwner: 決定 LiveData 觀察者的生命周期綁定

    • 使用 Activity 作為 LifecycleOwner:觀察者綁定到 Activity 的生命周期
    • 使用 Fragment 作為 LifecycleOwner:觀察者綁定到 Fragment 的生命周期

二、測試場景與結果

場景1:Fragment1 使用 Activity 的 ViewModelStoreOwner 和 LifecycleOwner

setValue 來源: Activity 的 viewModel
測試說明: Activity 調(diào)用 setValue,Activity 未 observe

組件 ViewModelStoreOwner LifecycleOwner 是否 observe 觀察結果
Activity Activity Activity ? 未 observe -
Fragment1 Activity Activity ? observe ? 觀察到
Fragment2 Fragment Fragment ? observe ? 無法觀察到

結論: Fragment1 與 Activity 共享 ViewModel 實例,可以觀察到 Activity 設置的值;Fragment2 使用獨立的 ViewModel 實例,無法觀察到。


場景2:Fragment1 使用 Activity 的 ViewModelStoreOwner,F(xiàn)ragment 自身的 LifecycleOwner

setValue 來源: Activity 的 viewModel
測試說明: Activity 調(diào)用 setValue,Activity 未 observe

組件 ViewModelStoreOwner LifecycleOwner 是否 observe 觀察結果
Activity Activity Activity ? 未 observe -
Fragment1 Activity Fragment ? observe ? 觀察到
Fragment2 Fragment Fragment ? observe ? 無法觀察到

結論: Fragment1 雖然使用 Fragment 作為 LifecycleOwner,但因為與 Activity 共享 ViewModel 實例,仍能觀察到 Activity 設置的值。


場景3:Fragment1 使用 Fragment 的 ViewModelStoreOwner,Activity 的 LifecycleOwner

setValue 來源: Activity 的 viewModel
測試說明: Activity 調(diào)用 setValue,Activity 未 observe

組件 ViewModelStoreOwner LifecycleOwner 是否 observe 觀察結果
Activity Activity Activity ? 未 observe -
Fragment1 Fragment Activity ? observe ? 無法觀察到
Fragment2 Fragment Fragment ? observe ? 無法觀察到

結論: Fragment1 使用獨立的 ViewModel 實例,即使使用 Activity 作為 LifecycleOwner,也無法觀察到 Activity 的 ViewModel 實例的變化。


場景4:Activity 和 Fragment1 都使用 Activity 的 ViewModelStoreOwner 和 LifecycleOwner

setValue 來源: Fragment1 的 viewModel
測試說明: Fragment1 調(diào)用 setValue,Activity 也 observe

組件 ViewModelStoreOwner LifecycleOwner 是否 observe 觀察結果
Activity Activity Activity ? observe ? 觀察到
Fragment1 Activity Activity ? observe ? 觀察到
Fragment2 Fragment Fragment ? observe ? 無法觀察到

結論: Activity 和 Fragment1 共享同一個 ViewModel 實例,當 Fragment1 設置值時,Activity 和 Fragment1 都能觀察到變化;Fragment2 使用獨立的 ViewModel 實例,無法觀察到。


場景5:Fragment1 使用 Fragment 的 ViewModelStoreOwner,Activity 的 LifecycleOwner

setValue 來源: Fragment1 的 viewModel
測試說明: Fragment1 調(diào)用 setValue,Activity 也 observe

組件 ViewModelStoreOwner LifecycleOwner 是否 observe 觀察結果
Activity Activity Activity ? observe ? 無法觀察到
Fragment1 Fragment Activity ? observe ? 觀察到
Fragment2 Fragment Fragment ? observe ? 無法觀察到

結論: Fragment1 使用獨立的 ViewModel 實例,當 Fragment1 設置值時,只有 Fragment1 能觀察到自己的 ViewModel 變化;Activity 雖然 observe,但因為使用的是不同的 ViewModel 實例,無法觀察到 Fragment1 設置的值。


三、關鍵發(fā)現(xiàn)總結

1. ViewModelStoreOwner 的作用

ViewModelStoreOwner 效果
Activity Activity 和所有使用 Activity 的 Fragment 共享同一個 ViewModel 實例
Fragment 每個 Fragment 擁有獨立的 ViewModel 實例,互不影響

2. LifecycleOwner 的作用

LifecycleOwner 效果
Activity 觀察者綁定到 Activity 的生命周期,Activity 銷毀時自動移除觀察者
Fragment 觀察者綁定到 Fragment 的生命周期,F(xiàn)ragment 銷毀時自動移除觀察者

3. 觀察 LiveData 變化的條件

? 能觀察到變化的條件

  • 必須使用同一個 ViewModel 實例(通過相同的 ViewModelStoreOwner 獲?。?/li>
  • 必須在該 ViewModel 實例上調(diào)用 setValue()postValue()
  • 必須在該 ViewModel 實例上調(diào)用 observe() 注冊觀察者
  • 觀察者綁定的 LifecycleOwner 必須處于活躍狀態(tài)(STARTED 或 RESUMED)

? 無法觀察到變化的情況

  • 使用不同的 ViewModelStoreOwner 獲取 ViewModel(不同的 ViewModel 實例)
  • 在錯誤的 ViewModel 實例上設置值
  • 未調(diào)用 observe() 注冊觀察者
  • 觀察者綁定的 LifecycleOwner 處于非活躍狀態(tài)

4. 測試場景分組說明

場景組 setValue 來源 Activity 是否 observe 測試目的
場景1-3 Activity 的 viewModel ? 未 observe 測試 Activity 設置值,F(xiàn)ragment 觀察的情況
場景4-5 Fragment1 的 viewModel ? observe 測試 Fragment 設置值,Activity 和 Fragment 觀察的情況

四、最佳實踐建議

1. 共享數(shù)據(jù)場景

推薦配置

  • Activity 和需要共享數(shù)據(jù)的 Fragment 都使用 Activity 作為 ViewModelStoreOwner
  • 使用 ActivityFragment 作為 LifecycleOwner 都可以(取決于業(yè)務需求)
// Activity
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
viewModel.data.observe(this) { ... }

// Fragment
viewModel = ViewModelProvider(requireActivity()).get(MyViewModel::class.java)
viewModel.data.observe(this) { ... } // 或 observe(requireActivity()) { ... }

2. 獨立數(shù)據(jù)場景

推薦配置

  • 每個 Fragment 使用 Fragment 自身 作為 ViewModelStoreOwner
  • 使用 Fragment 自身 作為 LifecycleOwner
// Fragment
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
viewModel.data.observe(this) { ... }

3. 注意事項

?? 避免的配置

  • Fragment 使用 Fragment 作為 ViewModelStoreOwner,但使用 Activity 作為 LifecycleOwner(容易造成混淆)
  • 在 Activity 中設置值,但 Fragment 使用獨立的 ViewModel 實例(無法觀察到變化)

五、測試代碼示例

場景4 的完整實現(xiàn)(推薦配置)

// Activity
class TestLiveDataActivity : BaseActivity() {
    private lateinit var viewModel: TestLiveDataViewModel
    
    override fun initData() {
        viewModel = ViewModelProvider(this).get(TestLiveDataViewModel::class.java)
        viewModel.testLiveData.observe(this) { value ->
            LogUtil.d("TestLiveData", "Activity觀察到: $value")
        }
    }
}

// Fragment1
class TestLiveDataFragment1 : BaseFragment() {
    private lateinit var viewModel: TestLiveDataViewModel
    
    override fun initData() {
        viewModel = ViewModelProvider(requireActivity()).get(TestLiveDataViewModel::class.java)
        viewModel.testLiveData.observe(this) { value ->
            LogUtil.d("TestLiveData", "Fragment1觀察到: $value")
        }
    }
}

// Fragment2
class TestLiveDataFragment2 : BaseFragment() {
    private lateinit var viewModel: TestLiveDataViewModel
    
    override fun initData() {
        viewModel = ViewModelProvider(this).get(TestLiveDataViewModel::class.java)
        viewModel.testLiveData.observe(this) { value ->
            LogUtil.d("TestLiveData", "Fragment2觀察到: $value")
        }
    }
}

六、總結

  1. ViewModelStoreOwner 決定數(shù)據(jù)共享:使用相同的 ViewModelStoreOwner 才能共享同一個 ViewModel 實例
  2. LifecycleOwner 決定生命周期綁定:觀察者會跟隨 LifecycleOwner 的生命周期自動管理
  3. 觀察變化的前提:必須在同一個 ViewModel 實例上設置值和觀察
  4. 推薦做法:需要共享數(shù)據(jù)時,Activity 和 Fragment 都使用 Activity 作為 ViewModelStoreOwner
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容