JetPack

LiveDataBus 使用

2019-12-24  本文已影响0人  放肆滴微笑

rxbus

优点 效率高,无内存泄露、UI和实时数据保持一致
缺点: 依赖包 2.2M 比较大

EventBus

优点 使用简单、UI和实时数据保持一致
缺点: 混淆问题,无法感知生命周期 很难追踪到发布源

LiveDataBus

优点:
UI和实时数据保持一致
避免内存泄露,内部实现
不会在产生由于Activity处于stop状态而引起崩溃
不需要解决生命周期带来的问题
实时数据刷新
解决Configuration chanage问题
使用系统api

liveData 是一个数据持有类,持有数据并且这个数据能被观察者所监听到,而且他是和lifecycle绑定,具有声明周期感知,解决内存泄露和引用问题

所有的框架,如果和声明周期相关,里面肯定有lifecycle

lifecycle 是android 官方退出的官方架构之一,他是具有生命周期感知的,不单能够监听Activity和Fragment的生命周期,还能回调相应的方法,同时他能够实时的获取当前Activity和fragment的状态

image.png

LiveDataBus使用中有个缺点,在A页面发送消息,再进入B页面,这个时候B页面还能接受到消息,是个错误,
因为从事件上来说,需要注册后,再发送,

发送一个事件

# MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);  //调用父类
    }
}

# LiveData
protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        // 发现是个线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

# LiveData
// 找到线程方法
 private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);   // 通过它来赋值
        }
    };

@MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;  // 发现mVersion ++ 也就是发送一个事件 增加
        mData = value;
        dispatchingValue(null);
    }

通过源码也就明白 mVersion 和 mLastVersion 开始都是0,发送一个事件mVersion +1 ,

下面,通过hook 来改变
在LiveDataBus中,也就是通过onChanged方法来接收监听,我们可以在接收到事件后,拦截监听,
通过代码发现 observer.mLastVersion >= mVersion 这块如果大于或等于就可以拦截,退出这个方法,从而让observer.mObserver.onChanged((T) mData);不能执行,起到拦截的作用

private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;   // 可以在这里进行hook 让他们相等
        }
        observer.mLastVersion = mVersion;
        // 进行发送 onChanged 事件
        observer.mObserver.onChanged((T) mData);
    }

mVersion 就是LiveData 的成员变量,可以直接获取到
mLastVersion 是ObserverWrapper的成员变量
发现considerNotify方法是通过for循环遍历mObservers,我们找到mObservers

void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    //  通过遍历 执行这个方法
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }


private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

发现 SafeIterableMap 的value 又是 Entry

# SafeIterableMap
protected Entry<K, V> get(K k) {
        Entry<K, V> currentNode = mStart;
        while (currentNode != null) {
            if (currentNode.mKey.equals(k)) {
                break;
            }
            currentNode = currentNode.mNext;
        }
        return currentNode;
    }

所以我们需要先找到mObservers,再获取其中的Entry,就获得到ObserverWrapper,从而改变mLastVersion,需要注意得到的ObserverWrapper是子类LifecycleBoundObserver,需要获取父类

下面是完整代码

public class LiveDataBus {
    private static final String TAG = "LiveDataBus";
    private static LiveDataBus liveDataBus = new LiveDataBus();
    // 创建一个容器 装载所有的订阅者
    private Map<String, BusMutableLiveData<Object>> bus;

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

    public static LiveDataBus getInstance() {
        return liveDataBus;
    }

    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);
    }

    public static class BusMutableLiveData<T> extends MutableLiveData<T> {
        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
            super.observe(owner, observer);
            try {
                hook(observer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void hook(Observer observer) throws Exception {
            // 获取 LiveData 的类对象
            Class<LiveData> liveDataClass = LiveData.class;
            //  获取 mVersion 对象
            Field mVersionField = liveDataClass.getDeclaredField("mVersion");
            mVersionField.setAccessible(true);
            // 获取 mObservers 对象
            Field mObserversField = liveDataClass.getDeclaredField("mObservers");
            mObserversField.setAccessible(true);

            // 通过get 能获取到mObservers这个成员变量
            // SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers
            // 因为MutableLiveData 是 LiveData的子类,所以直接this 就能获取
            Object mObservers = mObserversField.get(this);

            // 获取map 的get方法 ,map 获取的value 是Object类型
            Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);
            get.setAccessible(true);

            // 执行get, mObservers 里面就是 Observer 和 ObserverWrapper,所以直接传递observer
            Object invoke = get.invoke(mObservers, observer);
            Object observerWrapper = null;

            // 如果 执行结果不为空 并且也是Entry类型,说明结果对的
            if (invoke != null && invoke instanceof Map.Entry) {
                observerWrapper = ((Map.Entry) invoke).getValue();
            }

            if (observerWrapper == null) {
                throw new NullPointerException();
            }

            // 这个时候获取到mObservers 的value 再来改变mLastVersion 的值
            Class<?> observerWrapperClass = observerWrapper.getClass();
            Log.i(TAG, "observerWrapperClass: "+observerWrapperClass);
            // 发现获取的类类型 是 LifecycleBoundObserver,是 ObserverWrapper 子类,所以要 getSuperclass
            Field mLastVersion = observerWrapperClass.getSuperclass().getDeclaredField("mLastVersion");
            mLastVersion.setAccessible(true);

            // 得到 mVersionField 的值
            Object o = mVersionField.get(this);
            // 将mVersionField的值 付给 mLastVersion
            mLastVersion.set(observerWrapper, o);
        }
    }

使用
通过postValue发送事件,可以传递事件名,和事件类型,注意发送事件名对应的类型 要和接收的类型一致

# 发送
LiveDataBus.getInstance().with("wx", String.class).postValue("Two");

# 接收
LiveDataBus.getInstance().with("wx",String.class).observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.i(TAG, "onChanged: "+s);
            }
        });
上一篇 下一篇

猜你喜欢

热点阅读