LiveData学习记

1,267 阅读3分钟

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 使用