安卓LiveDataBus使用记录

创建三个文件

BusMutableLiveData.kt
package com.donews.common.livedatabus;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 应用模块: liveData
 * <p>
 * 类描述: 扩展liveData hook源码拦截实现非粘性事件
 * <p>
 *
 * 作者: created by honeylife<br>
 * 日期:2020-02-07
 */
public class BusMutableLiveData<T> extends MutableLiveData<T> {

    private Map<Observer,Observer> observerMap = new HashMap<>();
    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        super.observe(owner, observer);
        try {
            hook(observer);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void observeForever(@NonNull Observer<? super T> observer) {
        if (!observerMap.containsKey(observer)){
            observerMap.put(observer,new ObserverWrapper(observer));
        }
        super.observeForever(observerMap.get(observer));
    }

    @Override
    public void removeObserver(@NonNull Observer<? super T> observer) {
        Observer realObserver = null;
        if (observerMap.containsKey(observer)){
            realObserver = observerMap.remove(observer);
        }else {
            realObserver = observer;
        }
        super.removeObserver(realObserver);
    }

    /**
     * hook源码实现,拦截订阅之前的事件
     * @param observer observer
     * */
    private void hook(Observer<? super T> observer) throws Exception {
        //get wrapper's version
        Class<LiveData> classLiveData = LiveData.class;
        Field fieldObservers = classLiveData.getDeclaredField("mObservers");
        fieldObservers.setAccessible(true);
        Object objectObservers = fieldObservers.get(this);
        Class<?> classObservers = objectObservers.getClass();
        Method methodGet = classObservers.getDeclaredMethod("get", Object.class);
        methodGet.setAccessible(true);
        Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);
        Object objectWrapper = null;
        if (objectWrapperEntry instanceof Map.Entry) {
            objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
        }
        if (objectWrapper == null) {
            throw new NullPointerException("Wrapper can not be bull!");
        }
        Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass();
        Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
        fieldLastVersion.setAccessible(true);
        //get livedata's version
        Field fieldVersion = classLiveData.getDeclaredField("mVersion");
        fieldVersion.setAccessible(true);
        Object objectVersion = fieldVersion.get(this);
        //set wrapper's version
        fieldLastVersion.set(objectWrapper, objectVersion);
    }
}
ObserverWrapper.kt
package com.donews.common.livedatabus;

import androidx.lifecycle.Observer;

/**
 * 应用模块: liveData
 * <p>
 * 类描述: Observer 包装类
 * <p>
 *
 * 作者: created by honeylife<br>
 * 日期:2020-02-07
 */
public class ObserverWrapper<T> implements Observer<T> {

    private Observer<T> observer;

    public ObserverWrapper(Observer<T> observer) {
        this.observer = observer;
    }

    @Override
    public void onChanged(T t) {
       if (observer != null){
           if (isCallOnObserve()){
               return;
           }
           observer.onChanged(t);
       }
    }

    private boolean isCallOnObserve() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        if (stackTrace != null && stackTrace.length > 0) {
            for (StackTraceElement element : stackTrace) {
                if ("android.arch.lifecycle.LiveData".equals(element.getClassName()) &&
                        "observeForever".equals(element.getMethodName())) {
                    return true;
                }
            }
        }
        return false;
    }
}
LiveDataBus.kt
package com.donews.common.livedatabus;

import androidx.lifecycle.MutableLiveData;

import java.util.HashMap;
import java.util.Map;

/**
 * 应用模块: liveData
 * <p>
 * 类描述: 基于liveData的事件总线 1.关联activity / fragment 的生命周期 自动识别活动状态触发更新 2.可以发送两种事件
 * 普通事件 & 粘性事件
 *
 * <p>
 *
 * 作者: created by honeylife<br>
 * 日期:2020-02-07
 */
public class LiveDataBus
{
    
    /**
     * 粘性事件集合
     */
    private final Map<String, MutableLiveData> stickyBus;
    
    /**
     * 普通事件结合
     */
    private final Map<String, BusMutableLiveData> bus;

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

    public static LiveDataBus getInstance() {
        return singleHolder.SINGLE_BUS;
    }

    private static class singleHolder {
        private static final LiveDataBus SINGLE_BUS = new LiveDataBus();
    }

    public MutableLiveData<Object> with(String key) {
        return with(key, Object.class);
    }

    public <T> MutableLiveData<T> with(String key, Class<T> type) {
        if (!bus.containsKey(key)) {
            bus.put(key, new BusMutableLiveData<T>());
        }
        return  bus.get(key);
    }

    public MutableLiveData<Object> withSticky(String key) {
        return withSticky(key, Object.class);
    }

    public <T> MutableLiveData<T> withSticky(String key, Class<T> type) {
        if (!stickyBus.containsKey(key)) {
            stickyBus.put(key, new MutableLiveData<T>());
        }
        return  stickyBus.get(key);
    }


}

具体使用:

//发送数据
LiveDataBus.getInstance().with("key").setValue("需要发送的数据");



//接收数据
 LiveDataBus.getInstance()
            .with("key", String::class.java)
            .observe(requireActivity()) {
            //it就是接收到的数据
            val result = it
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小趴菜8227

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值