美文网首页
LiveData的使用和分析

LiveData的使用和分析

作者: 壹元伍角叁分 | 来源:发表于2021-12-12 13:05 被阅读0次

一、认识篇

一般情况下,LiveData要配合ViewModel一起使用的。这篇单独学习LiveData。

LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。
这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

二、使用篇

1、先构建一个单例类

object MyLiveData {
    // 这里为info1的MutableLiveData 懒加载初始化(懒加载:用到时才加载)
    val data: MutableLiveData<String> by lazy {
        MutableLiveData()
    }

    init {
        data.value = "初始值0"
    }
}

2、在activity中注册监听

MyLiveData.data.value = "我设置了...000"

MyLiveData.data.value = "我设置了...111"

MyLiveData.data.observe(this, { t -> // 数据发生了而变化
    // 文本先显示"我设置了...111",2s后修改成"我又设置了...222"
    // 最开始显示的是在观察者订阅前的一个消息,就是消息的粘性。
    tv_live_data.text = t
})

thread {
    Thread.sleep(2000)
    // postValue会自动切换到主线程中去设置
    MyLiveData.data.postValue("我又设置了...222")
}

三、原理篇

1、MutableLiveData

继承了LiveData,是一个可变的LiveData。是一个被观察者,是一个数据持有者。提供了 setValue 和 postValue方法,其中postValue可以在子线程调用 postValue方法。

public class MutableLiveData<T> extends LiveData<T> {

    public MutableLiveData(T value) {
        super(value);
    }

    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

2、注册流程

有两个参数,第一个是被观察者的生命周期,第二个是观察者

MyLiveData.data.observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
    // 首先会通过LifecycleOwner获取Lifecycle对象然后获取Lifecycle 的State,如果是DESTROYED直接 return 了。忽略这次订阅
--> if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        return;
    }
    // 把LifecycleOwner和Observer包装成LifecycleBoundObserver对象。这个是重点。后面会分析下LifecycleBoundObserver
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    // mObservers是个map集合,将观察者放入map集合。
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

    // 给观察者的生命周期添加监听。
    // 这个代码和我们前面分析lifeCyclerView的代码相同。
    // 当owner也就是我们的activity的生命周期发生变化时,最终会调用wrapper的onStateChanged方法
    owner.getLifecycle().addObserver(wrapper);

3、LiveData的setValue()方法

protected void setValue(T value) {
    assertMainThread("setValue");
    // 这里的version 进行了+1
    mVersion++;
    mData = value;
    // 进行数据的分发。注意这里传入的参数为null
    dispatchingValue(null);
}

接着看dispatchingValue()方法

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            // initiator为null,走这里,遍历观察者
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                // 最后都是调用的是下面这个方法。
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

接着进入到considerNotify()方法。

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    // 再次校验状态
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    // 如果观察中的状态是大于LiveData中的verison,直接返回。
    // 还记得上面在setValue时,LiveData中的verison+1了,所以,正常情况下是继续往下走的
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    // 将观察者中的version也进行了赋值。
    observer.mLastVersion = mVersion;
    // 最终调用了observer.mObserver.onChanged((T) mData)方法。
    // 这个observer.mObserver 就是我们的 Observer接口,然后调用它的onChanged方法。
    observer.mObserver.onChanged((T) mData);
}

4、MutableLiveData.postValue()

子线程发送消息通知更新 UI。是怎么切换到主线程的呢?接下来我们来看一下源码

MyLiveData.data.postValue("我又设置了...222")
--> ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);@LiveData
    --> mDelegate.postToMainThread(runnable);@ArchTaskExecutor
        --> if (mMainHandler == null) { @DefaultTaskExecutor
               synchronized (mLock) {
                  if (mMainHandler == null) {
                      mMainHandler = createAsync(Looper.getMainLooper());
                  }
               }
            }
            // 在这里切换到主线程,执行mPostValueRunnable的run方法。
            mMainHandler.post(runnable);
private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }

            // 在主线程中设置了值。后面的逻辑就跟我们前面分析的一样了。
            setValue((T) newValue);
};

5、LifecycleBoundObserver

它包装了LifecycleOwner和Observer。

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    @NonNull
    final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);
        mOwner = owner;
    }

    @Override
    boolean shouldBeActive() {
        // 判断当前的 Lifecycle 的生命周期是否是活跃状态,会在回调观察则 Observer 的时候进行判断。
        // 只有在活跃状态,才会回调观察者Observer的onChanged方法。
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        // 再次校验activity的生命周期
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        
        // 销毁状态直接return,并移除观察者
        if (currentState == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            
            // shouldBeActive(),当activity的状态为STARTED或RESUMED时为true。
            activeStateChanged(shouldBeActive());
            
            // currentState置为activity的状态
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }
    
     @Override
     void detachObserver() {
          // 移除观察者Observer,解除订阅关系。
          mOwner.getLifecycle().removeObserver(this);
      }
}

三、去除黏性

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
    
            // 得到mVersion
            val mVersion: Field = liveDataClass.getDeclaredField("mVersion")
            mVersion.isAccessible = true
    
            // mLastVersion=mVersion
            val mVersionValue: Any = mVersion.get(this)
            mLastVersion.set(observerWraper, mVersionValue)
        }
    }
}

使用

  // Kotlin版本订阅观察者
OKLiveDataBusKT.with("data1", String::class.java).observe(this, {
     Toast.makeText(this, "Kotlin版本的 观察者:${it}", Toast.LENGTH_SHORT).show()
     Log.d("derry", "Kotlin版本的 观察者:${it}")
})

相关文章

网友评论

      本文标题:LiveData的使用和分析

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