美文网首页
LiveDataBus的入门

LiveDataBus的入门

作者: c3e73e0cbeb9 | 来源:发表于2019-04-08 09:55 被阅读0次

    1、了解LiveData

        1>什么是LiveDate?

    答:LiveData是Android官方提供的。LiveData是一个可以被观察的数据持有类,它可以感知并遵循Activity、Fragment或Service等组件的生命周期。正是由于LiveData对组件生命周期可感知特点,因此可以做到仅在组件处于生命周期的激活状态时才更新UI数据。(换成人话就是说:LiveData 是用来跨页(跨线程)通讯的类,官方给我们提供的,我们只管用就行。不用管生命周期带来的内存泄漏等相关问题)

        2>LiveDate的优点

    1、UI和实时数据保持一致 因为LiveData采用的是观察者模式,这样一来就可以在数据发生改变时获得通知,更新UI。

    2、避免内存泄漏 观察者被绑定到组件的生命周期上,当被绑定的组件销毁(destroy)时,观察者会立刻自动清理自身的数据。

    3、不会再产生由于Activity处于stop状态而引起的崩溃

    2、LiveDataBus、EventBus和RxBus的比较

    1>EventBus

    2>RxBUs

    在RxJava中有个Subject类,它继承Observable类,同时实现了Observer接口,因此Subject可以同时担当订阅者和被订阅者的角色,我们使用Subject的子类PublishSubject来创建一个Subject对象(PublishSubject只有被订阅后才会把接收到的事件立刻发送给订阅者),在需要接收事件的地方,订阅该Subject对象,之后如果Subject对象接收到事件,则会发射给该订阅者,此时Subject对象充当被订阅者的角色。

    完成了订阅,在需要发送事件的地方将事件发送给之前被订阅的Subject对象,则此时Subject对象作为订阅者接收事件,然后会立刻将事件转发给订阅该Subject对象的订阅者,以便订阅者处理相应事件,到这里就完成了事件的发送与处理。

    最后就是取消订阅的操作了,RxJava中,订阅操作会返回一个Subscription对象,以便在合适的时机取消订阅,防止内存泄漏,如果一个类产生多个Subscription对象,我们可以用一个CompositeSubscription存储起来,以进行批量的取消订阅。

    3>LiveDataBus

    实现代码

    代码中有注释,就不在赘述

    ```

    public final class LiveDataBus {

    private final Map>bus;

        private LiveDataBus() {

    bus =new HashMap<>();

        }

    private static class SingletonHolder {

    private static final LiveDataBusDEFAULT_BUS =new LiveDataBus();

        }

    public static LiveDataBusget() {

    return SingletonHolder.DEFAULT_BUS;

        }

    public MutableLiveDatawith(String key, Class type) {

    if (!bus.containsKey(key)) {

    bus.put(key, new BusMutableLiveData<>());

            }

    return (MutableLiveData)bus.get(key);

        }

    public MutableLiveDatawith(String key) {

    return with(key, Object.class);

        }

    /**

    * 解决observeForever内存泄漏问题

    *

        * @param <T>

        */

        private static class ObserverWrapperimplements Observer {

    private Observerobserver;

            public ObserverWrapper(Observer observer) {

    this.observer = observer;

            }

    @Override

            public void onChanged(@Nullable 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;

            }

    }

    /**

    * 解决 订阅者会收到订阅之前发布的消息 问题

    *

        * @param <T>

        */

        private static class BusMutableLiveDataextends MutableLiveData {

    private MapobserverMap =new HashMap<>();

            @Override

            public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {

    super.observe(owner, observer);

                try {

    hook(observer);

                }catch (Exception e) {

    e.printStackTrace();

                }

    }

    @Override

            public void observeForever(@NonNull Observer observer) {

    if (!observerMap.containsKey(observer)) {

    observerMap.put(observer, new ObserverWrapper(observer));

                }

    super.observeForever(observerMap.get(observer));

            }

    @Override

            public void removeObserver(@NonNull Observer observer) {

    Observer realObserver =null;

                if (observerMap.containsKey(observer)) {

    realObserver =observerMap.remove(observer);

                }else {

    realObserver = observer;

                }

    super.removeObserver(realObserver);

            }

    /**

    * 利用hook技术修改源码的实现逻辑

    *

            * @param observer

            * @throws Exception

    */

            private void hook(@NonNull Observer observer)throws Exception {

    //拿到LiveData

                Class classLiveData = LiveData.class;

                //找到LiveData中mObservers字段

                Field fieldObservers = classLiveData.getDeclaredField("mObservers");

                fieldObservers.setAccessible(true);

                Object objectObservers = fieldObservers.get(this);

                Class classObservers = objectObservers.getClass();

                //调用mObservers的get方法

                Method methodGet = classObservers.getDeclaredMethod("get", Object.class);

                methodGet.setAccessible(true);

                //调用get方法拿到mObservers中单个的Entry值

                Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);

                Object objectWrapper =null;

                if (objectWrapperEntryinstanceof Map.Entry) {

    //拿到Observer

                    objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();

                }

    if (objectWrapper ==null) {

    throw new NullPointerException("Wrapper can not be bull!");

                }

    //拿到Observer的父类(ObserverWrapper)

                Class classObserverWrapper = objectWrapper.getClass().getSuperclass();

                Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");

                fieldLastVersion.setAccessible(true);

                //拿到LiveData中的mVersion

                Field fieldVersion = classLiveData.getDeclaredField("mVersion");

                fieldVersion.setAccessible(true);

                Object objectVersion = fieldVersion.get(this);

                //把observer.mLastVersion的值改为mVersion的值

                fieldLastVersion.set(objectWrapper, objectVersion);

            }

    }

    }

    ```

    参考:手写LiveDataBus

    相关文章

      网友评论

          本文标题:LiveDataBus的入门

          本文链接:https://www.haomeiwen.com/subject/meovbqtx.html