注册

LiveData学习记

LiveData 使用


var liveData: MutableLiveData<String>? = null
//初始化
liveData = MutableLiveData()
// 设置 observe
liveData?.observe(this, {
Log.e("Main2", "2界面接收数据 = $it")
Toast.makeText(this, "2界面接收数据 = $it", Toast.LENGTH_LONG).show()
})
// 发送值
liveData?.value = "2界面发送数据 $indexValue"

LiveData 是针对同一个界面数据相互传递, 配合 MVVM 使用


如果想跨界面使用 比如 Activity1 想传值 给 Activity2 可以把LiveData 下沉(二次封装)


package com.one_hour.test_livedata
import androidx.lifecycle.MutableLiveData
object LiveDataBusBeta{
//创建一个Map 管理 LiveData
private val liveDataMap: MutableMap<String, MutableLiveData<Any>> = HashMap()
// 设置一个 key
fun <T> getLiveData(key: String) : MutableLiveData<T>? {
if (!liveDataMap.containsKey(key)) {
liveDataMap.put(key, MutableLiveData<Any>())
}
return liveDataMap[key] as MutableLiveData<T>
}
fun removeMapLiveData(key : String) {
liveDataMap.remove(key)
}
}

像这样下沉后会出现 Bug, 如场景:当界面Activity1 向未创建的Activity2 发送消息时,会在Activity2 创建时 出现从界面1传过来的数据,这是我们不需要的。(现象出现叫 消息粘性)


什么是粘性事件

即发射的事件如果早于注册,那么注册之后依然可以接收到的事件称为粘性事件


消息粘性 咋个形成的 ?
先创建 new MutableLiveData -> setValue -> observe(绑定监听)


LiveData 绑定(observe)源码

    @MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}


1.


owner.getLifecycle() 获取的是 Lifecycle 监听Activity 生命周期变化的流程
androidx.appcompat.app.AppCompatActivity (继承)-> androidx.fragment.app.FragmentActivity (继承)-> androidx.activity.ComponentActivity (继承)->androidx.core.app.ComponentActivity( 实现 LifecycleOwner) -> 现在 实例化 private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);


androidx.core.app.ComponentActivity( 实现 LifecycleOwner)


@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
//添加一个 mLifecycleRegistry 状态管理
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
super.onSaveInstanceState(outState);
}

androidx.activity.ComponentActivity( 实现 LifecycleOwner)


    @CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
//设置 lifecycle 当前状态
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}

androidx.fragment.app.FragmentActivity


final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);
//开始绑定什么周期 调用 handleLifecycleEvent 绑定状态
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.xxx);

2.


** owner.getLifecycle().addObserver(wrapper); 中 addObserver 调用了 androidx.lifecycle.LifecycleRegistry的 addObserver,而LifecycleRegistry是在FragmentActivity类中实例化获取**


    @Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}

boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
、、、、、省略代码
}

statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState)); 在循环中一直调用


    static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;

ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}

void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}

LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); 监听状态改变 并且
在ObserverWithState 中调用了 mLifecycleObserver.onStateChanged(owner, event); -》mLifecycleObserver 指的就是 LifecycleBoundObserver


class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver


        @Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 这里是如果状态 是可见的 那么就发送消息
// 就调用 class LifecycleBoundObserver extends ObserverWrapper 父类 ObserverWrapper 的方法
//shouldBeActive() 获取 mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); 状态 是否可见
activeStateChanged(shouldBeActive());
}

class LifecycleBoundObserver extends ObserverWrapper 父类 ObserverWrapper 的方法 并分发 dispatchingValue 值


        void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
// 调用 dispatchingValue 回到 abstract class LiveData<T> 类里面的 dispatchingValue 方法
dispatchingValue(this);
}
}
}

dispatchingValue 都调用了相同的函数 considerNotify


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

considerNotify 中 observer.mObserver.onChanged 回调数据


    private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}

解决粘性代码


  • 方法1

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer


class BaseLiveData<T> : MutableLiveData<T>() {
private var isSticky: Boolean = false
private var mStickyData: T? = null
private var mVersion = 0

override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
if (isSticky) {
super.observe(owner, observer)
} else {
super.observe(owner, CustomObserver<T>(this, observer))
}

}

/**
* 发送非粘性数据
*/
override fun setValue(value: T) {
mVersion++
isSticky = false
super.setValue(value)
}

override fun postValue(value: T) {
mVersion++
isSticky = false
super.postValue(value)
}

/**
* 发送粘性数据
*/
fun setStickyData(data: T?) {
mStickyData = data
isSticky = true
setValue(data!!)
}

fun postStickyData(mStickyData: T?) {
this.mStickyData = mStickyData
isSticky = true
super.postValue(mStickyData!!)
}

inner class CustomObserver<T>(val mLiveData: BaseLiveData<T>, var mObserver: Observer<in T>?,
var isSticky: Boolean = false) : Observer<T> {

private var mLastVersion = mLiveData.mVersion

override fun onChanged(t: T) {
if (mLastVersion >= mLiveData.mVersion) {
if (isSticky && mLiveData.mStickyData != null) {
mObserver?.onChanged(mLiveData.mStickyData)
}
return
}
mLastVersion = mLiveData.mVersion
mObserver?.onChanged(t)

}

}
}


  • 方法2

利用反射 修改 observer.mLastVersion 值
observer.mLastVersion 的 获取值的调用链 :
observer.mLastVersion -》considerNotify (iterator.next().getValue()) -> mObservers (SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>()) -> ObserverWrapper(int mLastVersion = START_VERSION;) (子类LifecycleBoundObserver, 但是只有父类 ObserverWrapper 才有 mLastVersion, 所以获取父类的 mLastVersion 进行修改)


import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import java.lang.reflect.Field
import java.lang.reflect.Method


class BaseUnStickyLiveData<T> : MutableLiveData<T>() {

private var isSticky = false

override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
if (!isSticky) {
hookClass(observer)
}
}

override fun setValue(value: T) {
isSticky = false
super.setValue(value)
}

override fun postValue(value: T) {
isSticky = false
super.postValue(value)
}

fun setStickyValue(value: T) {
isSticky = true
super.setValue(value)
}

fun setStickyPostValue(value: T) {
isSticky = true
super.postValue(value)
}

private fun hookClass(observer: Observer<in T>) {
val liveDataClass = LiveData::class.java
try {
//获取field private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers
val mObservers: Field = liveDataClass.getDeclaredField("mObservers")
mObservers.setAccessible(true)

//获取SafeIterableMap集合mObservers
val observers: Any = mObservers.get(this)

//获取SafeIterableMap的get(Object obj)方法
val observersClass: Class<*> = observers.javaClass
val methodGet: Method = observersClass.getDeclaredMethod("get", Any::class.java)
methodGet.setAccessible(true)

//获取到observer在集合中对应的ObserverWrapper对象
val objectWrapperEntry: Any = methodGet.invoke(observers, observer)
var objectWrapper: Any? = null
if (objectWrapperEntry is Map.Entry<*, *>) {
objectWrapper = objectWrapperEntry.value
}
if (objectWrapper == null) {
//throw NullPointerException("ObserverWrapper can not be null")
return
}

// 获取ListData的mVersion
val mVersion: Field = liveDataClass.getDeclaredField("mVersion")
mVersion.setAccessible(true)
val mVersionValue: Any = mVersion.get(this)

//获取ObserverWrapper的Class对象 LifecycleBoundObserver extends ObserverWrapper
val wrapperClass: Class<*> = objectWrapper.javaClass.superclass

//获取ObserverWrapper的field mLastVersion
val mLastVersion: Field = wrapperClass.getDeclaredField("mLastVersion")
mLastVersion.setAccessible(true)

//把当前ListData的mVersion赋值给 ObserverWrapper的field mLastVersion
mLastVersion.set(objectWrapper, mVersionValue)
} catch (e: Exception) {
if (BuildConfig.DEBUG) {
throw RuntimeException(e)
} else {
e.printStackTrace()
}
}
}
}

配合二次 封装的 LiveDataBusBeta 使用


作者:liqiang2199
链接:https://juejin.cn/post/7039269331405897742
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册