Androd 事件发布-订阅总线 框架 从EventBus到RxBus再到现在的LiveDataBus

EventBus

EventBus是一种用于Android的事件发布-订阅总线,由GreenRobot开发,Gihub地址是:EventBus。它简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。

EventBus、RxBus、LiveDataBus

其实这三个干的是同一件事,我们先分析一下这三个组件通信框架的优缺点:

EventBus的优缺点

优点:使用简单,能达到项目的基本需求
缺点:混淆问题,无法感知生命周期 ,很难追踪发布源

RxBus

优点:效率高,无内存泄漏。
缺点:基于RxJava,学习成本太大,而且依赖包有2.2m,对包大小有限制的应用不能使用,对apk产生一些负担。

LiveDataBus

优点: 使用极其简单
代码量很少
官方提供了很稳定的并且会一直维护的可依赖包
可感知组件Activity,Fragment,Service等)的生命周期
不会内存泄漏
缺点:需要学习。。。。

下面之间粘贴手写的LiveDataBus框架,你会发现代码量极少

先上使用的代码吧
订阅

LiveDataBus.get().with("mile",HuaWei.class).observe(this, new Observer<HuaWei>() {
            @Override
            public void onChanged(@Nullable HuaWei huaWei) {
                if (huaWei != null){
                    Toast.makeText(MainActivity.this,huaWei.getName()+"",Toast.LENGTH_SHORT).show();
                }
            }
        });

发布

HuaWei huaWei = new HuaWei("华为","mete10");
                LiveDataBus.get().with("mile",HuaWei.class).postValue(huaWei);

就是这么简单

LiveDataBus框架源码同样简单:


 * Created by mile on 2019/4/25.
 * 自定义时间总线框架
 */

public final class LiveDataBus {

    private final Map<String,MutableLiveData<Object>> bus;

    public LiveDataBus() {
        this.bus = new HashMap<>();
    }

    /*
    * 单利
    *
    * */
    private static class SingletonHolder{
        private static final LiveDataBus DEFAULT_BUS = new LiveDataBus();
    }

    public static LiveDataBus get(){
        return SingletonHolder.DEFAULT_BUS;
    }

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

    /**
     * 重写liveData的实现类的observe方法 在observe方法中进行Hook
     * */

    public static class BusMutableLiveData<T> extends MutableLiveData<T> {
        @Override
        public void observe(@NonNull LifecycleOwner owner,@NonNull  Observer<T> observer) {
            super.observe(owner, observer);

            try {
                hook(observer);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        private void hook(@NonNull Observer<T> observer) throws Exception{
            //observer.mlastVersion = mVersion;
            //首先获取到LiveData的class
            Class<LiveData> classLiveData = LiveData.class;
            //通过反射获取该class里面的observers属性对象
            Field fieldObservers = classLiveData.getDeclaredField("mObservers");
            //设置属性可以被访问
            fieldObservers.setAccessible(true);
            //获取的字段是this这个对象中的值 它的值是一个Map集合
            Object objectObservers = fieldObservers.get(this);
            //获取map对象的类型
            Class<?> classObservers = objectObservers.getClass();
            //获取到map对象中所有get方法
            Method methodGet = classObservers.getDeclaredMethod("get",Object.class);
            //设置get方法可以访问
            methodGet.setAccessible(true);
            //执行该get方法 传入objectObservers对象 然后传入observer作为key获取值
            Object objectWrapperEntry = methodGet.invoke(objectObservers,observer);
            //定义一个空的Object对象
            Object objectWrapper = null;
            //判断objectWapperEntry是否是Map.Entry类型
            if (objectWrapperEntry instanceof Map.Entry){
                //如果是 获取值并强转成object对象 //LifecycleBoundObserver
                objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
            }
            //判断是否为空
            if (objectWrapper == null){
                throw new NullPointerException("Wrapper can not be null!");
            }
            //如果不是空 就得到该Object对象的父类
            Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass();
            //通过他父类的class对象 获取到mLastVersion字段
            Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
            //设置mLastVersion字段可被访问
            fieldLastVersion.setAccessible(true);
            //获取到mVersion值
            Field fieldVersion = classLiveData.getDeclaredField("mVersion");
            //设置该值可以访问
            fieldVersion.setAccessible(true);
            //获取fieldVersion对象的类型
            Object objectVersion = fieldVersion.get(this);
            //把mVersion字段属性值设置给mLastVersion字段
            fieldLastVersion.set(objectWrapper,objectVersion);
        }
    }


}

源码下载

发布了117 篇原创文章 · 获赞 42 · 访问量 7万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览