一、认识篇
一般情况下,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}")
})
网友评论