Jetpack之livedatabBus源码解析

本文介绍了两种实现方式,一个是Java版本的OKLiveDataBusJava,通过单例模式移除粘性事件;另一个是Kotlin版本的OKLiveDataBusKT,它带有关闭粘性事件的开关。这两种实现都涉及到对LiveData内部结构的修改,以控制事件的传递。
摘要由CSDN通过智能技术生成

OkLiveDataBusJava

单例模式的 去掉粘性事件,Java版本

/**
 * 单例模式的 去掉粘性事件,Java版本
 */
public class  OKLiveDataBusJava {

    // 存放订阅者
    private Map<String, BusMutableLiveData<Object>> bus;
    private static OKLiveDataBusJava liveDataBus = new OKLiveDataBusJava();

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

    public static OKLiveDataBusJava getInstance() {
        return liveDataBus;
    }

    // 注册订阅者
    public synchronized  <T> BusMutableLiveData<T> with(String key, Class<T> type) {
        if (!bus.containsKey(key)) {
            bus.put(key, new BusMutableLiveData<>());
        }
        return (BusMutableLiveData<T>)  bus.get(key);
    }

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

    // 注册订阅者 重载
    /*public synchronized BusMutableLiveData<Object> with(String target) {
        return with(target, Object.class);
    }*/

    public static class BusMutableLiveData<T> extends MutableLiveData<T> {
        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
            super.observe(owner, observer); // 启用系统的功能  不写就破坏了

            hook(observer);
        }

        private void hook(Observer<? super T> observer) {
            try {
                // TODO 1.得到mLastVersion
                // 获取到LivData的类中的mObservers对象
                Class<LiveData> liveDataClass = LiveData.class;
                Field mObserversField = liveDataClass.getDeclaredField("mObservers");
                mObserversField.setAccessible(true);
                // 获取到这个成员变量的对象
                Object mObserversObject = mObserversField.get(this);
                // 得到map对象的class对象
                Class<?> mObserversClass = mObserversObject.getClass();
                // 获取到mObservers对象的get方法
                Method get = mObserversClass.getDeclaredMethod("get", Object.class);
                get.setAccessible(true);
                // 执行get方法
                Object invokeEntry = get.invoke(mObserversObject, observer);
                // 取到entry中的value
                Object observerWraper = null;
                if (invokeEntry != null && invokeEntry instanceof Map.Entry) {
                    observerWraper = ((Map.Entry) invokeEntry).getValue();
                }
                if (observerWraper == null) {
                    throw new NullPointerException("observerWraper is null");
                }
                // 得到observerWraperr的类对象
                Class<?> supperClass = observerWraper.getClass().getSuperclass();
                Field mLastVersion = supperClass.getDeclaredField("mLastVersion");
                mLastVersion.setAccessible(true);

                // TODO 2.得到mVersion
                Field mVersion = liveDataClass.getDeclaredField("mVersion");
                mVersion.setAccessible(true);

                // TODO 3.mLastVersion=mVersion
                Object mVersionValue = mVersion.get(this);
                mLastVersion.set(observerWraper, mVersionValue);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}




OKLiveDataBusKT

单例模式 去掉黏性事件(有关闭黏性的开关) KT的版本

object OKLiveDataBusKT {

    // 存放订阅者
    private val bus : MutableMap<String, BusMutableLiveData<Any>> by lazy { HashMap() }

    // 暴露一个函数,给外界注册 订阅者关系
    @Synchronized
    fun <T> with(key: String, type: Class<T>, isStick: Boolean = true) : BusMutableLiveData<T> {
        if (!bus.containsKey(key)) {
            bus[key] = BusMutableLiveData(isStick)
        }
        return bus[key] as BusMutableLiveData<T>
    }

    // Any? 是 Object ,  * 星投影 KT泛型的?  有点像 Java ?
    class BusMutableLiveData<T> private constructor() : MutableLiveData<T>() {

        var isStick: Boolean = false

        // 次构造
        constructor(isStick: Boolean) : this() {
            this.isStick = isStick
        }

        // 我是先执行
        override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
            super.observe(owner, observer) // 这句会执行父类的  // 启用系统的功能  不写就破坏了

            if (!isStick) {
                hook(observer = observer)
                Log.d("derry", "Kotlin版本的 不启用黏性")
            } else {
                Log.d("derry", "Kotlin版本的 启用黏性")
            }
        }

        private fun hook(observer: Observer<in T>) {
            // TODO 1.得到mLastVersion
            // 获取到LivData的类中的mObservers对象
            val liveDataClass = LiveData::class.java

            val mObserversField: Field = liveDataClass.getDeclaredField("mObservers")
            mObserversField.isAccessible = true // 私有修饰也可以访问

            // 获取到这个成员变量的对象  Any == Object
            val mObserversObject: Any = mObserversField.get(this)

            // 得到map对象的class对象   private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            val mObserversClass: Class<*> = mObserversObject.javaClass

            // 获取到mObservers对象的get方法   protected Entry<K, V> get(K k) {
            val get: Method = mObserversClass.getDeclaredMethod("get", Any::class.java)
            get.isAccessible = true // 私有修饰也可以访问

            // 执行get方法
            val invokeEntry: Any = get.invoke(mObserversObject, observer)

            // 取到entry中的value   is "AAA" is String    is是判断类型 as是转换类型
            var observerWraper: Any? = null
            if (invokeEntry != null && invokeEntry is Map.Entry<*, *>) {
                observerWraper = invokeEntry.value
            }
            if (observerWraper == null) {
                throw NullPointerException("observerWraper is null")
            }

            // 得到observerWraperr的类对象
            val supperClass: Class<*> = observerWraper.javaClass.superclass
            val mLastVersion: Field = supperClass.getDeclaredField("mLastVersion")
            mLastVersion.isAccessible = true

            // TODO 2.得到mVersion
            val mVersion: Field = liveDataClass.getDeclaredField("mVersion")
            mVersion.isAccessible = true

            // TODO 3.mLastVersion=mVersion
            val mVersionValue: Any = mVersion.get(this)
            mLastVersion.set(observerWraper, mVersionValue)
        }
    }

}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

gujunhe

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

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

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

打赏作者

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

抵扣说明:

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

余额充值