LiveDataBus详解(下)

本文详细解析了LiveDataBus的工作原理,并针对其重复消息接收的问题进行了深入分析与优化。通过调整LiveDataBus的实现方式,解决了页面重新加载时重复接收消息的问题。

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

LiveDataBus详解(上)

https://blog.youkuaiyun.com/weixin_37730482/article/details/74465947

 

上一章节,讲述了利用LiveData创建了一个LiveDataBus。实现类似RxBus和EventBus。但是项目中使用时,发现有一个问题。就是第二次进入页面时,会收到上一次发送的消息。但是发送消息的方法。并没有执行。

 

打断点调式  截图如下

也就是说,上一章节的代码。重新进入页面还是能收到消息。是因为

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
    //
    // we still first check observer.active to keep it as the entrance for events. So even if
    // the observer moved to an active state, if we've not received that event, we better not
    // notify for a more predictable notification order.
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    //noinspection unchecked
    observer.mObserver.onChanged((T) mData);
}

因为这种情况 

observer.mActive 肯定为true。

observer.shouldBeActive() 肯定也为true。

看截图 断点版本号不匹配 所以执行了observer.mObserver.onChanged((T) mData);代码。所以LiveData的onChanged方法执行,也就收到上一次发送的消息。解决办法

 

 

最终单例

public final class LiveDataBus {

    /**
     * 存储集合 存储的其实是LiveData对象
     */
    private final HashMap<String, MutableLiveData<LiveDataMsg>> bus;

    private LiveDataBus() {
        bus = new HashMap<>();
    }

    private static class ViewHolder {
        private static final LiveDataBus INSTANCE = new LiveDataBus();
    }

    public static LiveDataBus getInstance() {
        return ViewHolder.INSTANCE;
    }

    /**
     * 获取Key对应的LiveData
     *
     * @param key Key
     * @return LiveData对象
     */

    public MutableLiveData<LiveDataMsg> getLiveData(String key) {
        if (!bus.containsKey(key)) {
            bus.put(key, new MutableLiveData<>());
        }
        return bus.get(key);
    }

    /**
     * 主线程发送消息
     *
     * @param key         Key
     * @param liveDataMsg 消息实体类
     *                    内部调用setValue方法
     */

    public void sendMsgInMainThread(String key, LiveDataMsg liveDataMsg) {
        if (TextUtils.isEmpty(key) || null == liveDataMsg) return;
        getLiveData(key).setValue(liveDataMsg);
    }

    /**
     * 子线程发送消息
     *
     * @param key         Key
     * @param liveDataMsg 消息实体类
     *                    内部调用postValue方法
     */

    public void sendMsgInNewThread(String key, LiveDataMsg liveDataMsg) {
        if (TextUtils.isEmpty(key) || null == liveDataMsg) return;
        getLiveData(key).postValue(liveDataMsg);
    }

    /**
     * 接收消息
     *
     * @param key      Key
     * @param owner    LifecycleOwner拥有类
     * @param callback 回调
     */

    public void receivedMsg(final String key, LifecycleOwner owner, final MsgDataCallback callback) {
        if (TextUtils.isEmpty(key) || null == owner || null == callback) return;
        getLiveData(key).observe(owner, liveDataMsg -> {
            callback.getMsgCallback(liveDataMsg);
            clearMap(key);
        });
    }

    /**
     * 清空key对应的Map中的LiveData对象
     *
     * @param key Key
     */

    public void clearMap(String key) {
        if (!TextUtils.isEmpty(key)) {
            bus.remove(key);
        }
    }

    /**
     * 回调
     */

    public interface MsgDataCallback {
        void getMsgCallback(LiveDataMsg liveDataMsg);
    }

}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值