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 调用 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,Fragment 自身的 LifecycleOwner

setValue 来源: Activity 的 viewModel
测试说明: Activity 调用 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 调用 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 调用 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 调用 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 设置的值。


三、关键发现总结

1. ViewModelStoreOwner 的作用

ViewModelStoreOwner 效果
Activity Activity 和所有使用 Activity 的 Fragment 共享同一个 ViewModel 实例
Fragment 每个 Fragment 拥有独立的 ViewModel 实例,互不影响

2. LifecycleOwner 的作用

LifecycleOwner 效果
Activity 观察者绑定到 Activity 的生命周期,Activity 销毁时自动移除观察者
Fragment 观察者绑定到 Fragment 的生命周期,Fragment 销毁时自动移除观察者

3. 观察 LiveData 变化的条件

能观察到变化的条件

  • 必须使用同一个 ViewModel 实例(通过相同的 ViewModelStoreOwner 获取)
  • 必须在该 ViewModel 实例上调用 setValue()postValue()
  • 必须在该 ViewModel 实例上调用 observe() 注册观察者
  • 观察者绑定的 LifecycleOwner 必须处于活跃状态(STARTED 或 RESUMED)

无法观察到变化的情况

  • 使用不同的 ViewModelStoreOwner 获取 ViewModel(不同的 ViewModel 实例)
  • 在错误的 ViewModel 实例上设置值
  • 未调用 observe() 注册观察者
  • 观察者绑定的 LifecycleOwner 处于非活跃状态

4. 测试场景分组说明

场景组 setValue 来源 Activity 是否 observe 测试目的
场景1-3 Activity 的 viewModel ❌ 未 observe 测试 Activity 设置值,Fragment 观察的情况
场景4-5 Fragment1 的 viewModel ✅ observe 测试 Fragment 设置值,Activity 和 Fragment 观察的情况

四、最佳实践建议

1. 共享数据场景

推荐配置

  • Activity 和需要共享数据的 Fragment 都使用 Activity 作为 ViewModelStoreOwner
  • 使用 ActivityFragment 作为 LifecycleOwner 都可以(取决于业务需求)
// 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. 独立数据场景

推荐配置

  • 每个 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 的完整实现(推荐配置)

// 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 决定数据共享:使用相同的 ViewModelStoreOwner 才能共享同一个 ViewModel 实例
  2. LifecycleOwner 决定生命周期绑定:观察者会跟随 LifecycleOwner 的生命周期自动管理
  3. 观察变化的前提:必须在同一个 ViewModel 实例上设置值和观察
  4. 推荐做法:需要共享数据时,Activity 和 Fragment 都使用 Activity 作为 ViewModelStoreOwner
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容