浅谈 LiveData 的通知机制

本文探讨了Android中LiveData通知机制的问题,分析了当Activity或Fragment在后台时,LiveData如何处理数据更新并通知到前台。问题源于当组件从后台切换到前台时,只接收到了最后缓存的值。LiveData通过包装LifecycleOwner并监听其生命周期来决定何时通知观察者。解决方案是在恢复到前台时检查数据变化并重新加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LiveData 和 ViewModel 是 Google 官方的 MVVM 架构的一个组成部分。巧了,昨天分析了一个问题是 ViewModel 的生命周期导致的。今天又遇到了一个问题是 LiveData 通知导致的。而 ViewModel 的生命周期和 LiveData 的通知机制是它们的主要责任。所以,就这个机会我们也来分析一下 LiveData 通知的实现过程。

  1. 关于 ViewModel 的生命周期:《浅谈 LiveData 的通知机制》;
  2. 关于 MVVM 设计模式的基本应用,你可以参考这篇文章:《Android 架构设计:MVC、MVP、MVVM和组件化》.

1、一个 LiveData 的问题

今天所遇到的问题是这样的,

LiveData的问题

有两个页面 A 和 B,A 是一个 Fragment ,是一个列表的展示页;B 是其他的页面。首先,A 会更新页面,并且为了防止连续更新,再每次更新之前需要检查一个布尔值,只有为 false 的时候才允许从网络加载数据。每次加载数据之前会将该布尔值置为 true,拿到了结果之后置为 false. 这里拿到的结果是借助 LiveData 来通知给页面进行更新的。

现在,A 打开了 B,B 中对列表中的数据进行了更新,然后发了一条类似于广播的消息。此时,A 接收了消息并进行数据加载。过了一段时间,B 准备退出,再退出的时候又对列表中的项目进行了更新,所以此时又发出了一条消息。

B 关闭了,我们回到了 A 页面。但是,此时,我们发现 A 页面中的数据只包含了第一次的数据更新,第二次的数据更新没有体现在列表中。

用代码来描述的话大致是下面这样,

    // 类 A
    public class A extends Fragment {
   
   
    
        private boolean loading = false;

        private MyViewModel vm;

        // ......

        /**
         * Register load observer.
         */
        public void registerObservers() {
   
   
            vm.getData().observe(this, resources -> {
   
   
                loading = false;
                // ... show in list
            })
        }

        /**
         * Load data from server.
         */
        public void loadData() {
   
   
            if (loading) return;
            loading = true;
            vm.load();
        }

        /**
         * On receive message.
         */
        public void onReceive() {
   
   
            loadData();
        }
    }

    public class B extends Activity {
   
   

        public void doBusiness1() {
   
   
            sendMessage(MSG); // Send message when on foreground.
        }

        @Override
        public void onBackpressed() {
   
   
            // ....
            sendMessage(MSG); // Send message when back
        }
    }

    public class MyViewModel extends ViewModel {
   
   

        private MutableLiveData<Resoucres<Object>> data;

        public MutableLiveData<Resoucres<Object>> getData() {
   
   
            if (data == null) {
   
   
                data = new MutableLiveData<>(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值