LiveData的基本使用和原理解析

1.liveData的基本使用

1.1添加依赖

在build.gradle(app)中添加依赖

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-rc01"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.0-rc01"
}

自定义viewModel,持有LiveData

class MessageViewModel:ViewModel() {
     val message : MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}

MainActivity中代码如下

class MainActivity : AppCompatActivity() {
    private lateinit var  binding:ActivityMainBinding

    companion object{
        @JvmField
        var  viewModel = MessageViewModel()
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        initView()
    }

    private fun initView(){
        with(binding){
            //观察者
            var count = 0
            val observer = Observer<String>{
                Log.d("debug", it)
                tvMessage.text = it
            }
            //添加观察者
            viewModel.message.observe(this@MainActivity,observer)
            //在主线程中更新内容
            sendMessageInMainThread.setOnClickListener {
                viewModel.message.value = "在主线程中更新内容---$count"
            }
            //在子线程中更新内容
            sendMessageInSonThread.setOnClickListener {
                Thread{
                    viewModel.message.postValue("在子线程中更新内容---$count")
                    count++
                }.run()
            }
        }
    }
}

2.LiveData怎么添加观察者

类图如下
类图
事件分发的时序图如下,
liveData的事件分发

先找到添加观察者的入口
viewModel.message.observe(this@MainActivity,observer)
点击进入LiveData的observe()中

 @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    	//检查是否在主线程中调用observe(),如果不是抛出异常
        assertMainThread("observe");
        //检查Activity/Fragment的状态,如果已经DESTROYED,则直接退出,不用继续往下走
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //这里创建一个带生命周期的观察者对象
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //将这个观察者放入Map中,根据返回值,判断这个带生命周期的观察者是否和多个被观察者绑定,
        //如果和多个被观察者绑定则抛出异常
        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;
        }
        //这里获取Lifecycle的唯一实现类LifecycleRegistry的实例,将这个带生命周期的观察者添加进去
        owner.getLifecycle().addObserver(wrapper);
    }

点击addObserver(),进入LifecycleRegistry的方法中

@Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("addObserver");
        //初始化刚加入的LifecycleBoundObserver对象的状态,默认为INITIALIZED
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        //同时使用带生命周期的observer和初始化状态生成一个带状态和生命周期的observer,
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        //检查这个observer是否存在
        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;
        //计算observer要到达的状态,这里使用状态机
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        //进行状态同步,和targetState进行比较
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
                //将当前这个statefulObserver的状态压入栈中, 
                //private ArrayList<State> mParentStates = new ArrayList<>();
                //这是个ArrayList线程不安全
            pushParentState(statefulObserver.mState);
            final Event event = Event.upFrom(statefulObserver.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + statefulObserver.mState);
            }
            //进行事件分发
            statefulObserver.dispatchEvent(lifecycleOwner, event);
            //
            popParentState();
            // mState / subling may have been changed recalculate
            //更新targetState
            targetState = calculateTargetState(observer);
        }

        if (!isReentrance) {
            // we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }

进入同步


    // happens only on the top of stack (never in reentrance),
    // so it doesn't have to take in account parents
    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                    + "garbage collected. It is too late to change lifecycle state.");
        }
        while (!isSynced()) {
        //这里和moveToState()的mNewEventOccurred 一致
            mNewEventOccurred = false;
     
            // no need to check eldest for nullability, because isSynced does it for us.
            //无须检查 eldest的是否为空,isSynced()中已经帮我们做了
            //LifecycleRegister的状态和当前栈中最底层的observer的状态比较
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            	//调整LifecycleOwner的state,降级
                backwardPass(lifecycleOwner);
            }
                //LifecycleRegister的状态和当前栈中最顶层的observer的状态比较
            Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                    //将lifecycleOwner的状态升级
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }

关于这个状态的升级和降级和Activity的生命周期相关,下面代码是Lifecycle中的具体实现

   @NonNull
        public State getTargetState() {
            switch (this) {
                case ON_CREATE:
                case ON_STOP:
                    return State.CREATED;
                case ON_START:
                case ON_PAUSE:
                    return State.STARTED;
                case ON_RESUME:
                    return State.RESUMED;
                case ON_DESTROY:
                    return State.DESTROYED;
                case ON_ANY:
                    break;
            }
            throw new IllegalArgumentException(this + " has no target state");
        }

用图表示为:
状态转换示意图

 private boolean isSynced() {
        if (mObserverMap.size() == 0) {
            return true;
        }
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }

3.当数据发生变化,怎么通知观察者

viewModel.message.value = "在主线程中更新内容---$count"
从setValue这里进入,发现使用了父类LiveData的方法

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

进入LiveData中setValue(T value)

	    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        //将版本+1,初始值为 0
        mVersion++;
        mData = value;
        //如果有活跃的观察者,则分配值给他们
        dispatchingValue(null);
    }

继续跟踪进入 dispatchingValue()

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
    	//其中mSispatchingValue ,表示是否正在分发值
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
        	//这里做了个循环,mDispatchInvalidated 表示是否同时有其他线程调用分发
            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()

    @SuppressWarnings("unchecked")
    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;
        //回调匿名内部类,观察者接收到信息,更新内容流程结束
        observer.mObserver.onChanged((T) mData);
    }

4.LifeCycleOwner生命周期发生变化时,怎么及时通知观察者

这里Google官方用了一个比较奇妙的方法,因为Fragment的生命周期会跟随Activity的生命周期发生变化,
所以Google使用了一个无界面ReportFragment来感知生命周期的变化,当生命周期发生变化时,分发事件
在ComponentActivity的onCreate()方法中

    @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
     // Restore the Saved State first so that it is available to
     // OnContextAvailableListener instances
     mSavedStateRegistryController.performRestore(savedInstanceState);
     mContextAwareHelper.dispatchOnContextAvailable(this);
     super.onCreate(savedInstanceState);
     mActivityResultRegistry.onRestoreInstanceState(savedInstanceState);
     //这里进行注入
     ReportFragment.injectIfNeededIn(this);
     if (mContentLayoutId != 0) {
         setContentView(mContentLayoutId);
     }
 }

进入ReportFragment的injectIfNeededIn()中

public static void injectIfNeededIn(Activity activity) {
      if (Build.VERSION.SDK_INT >= 29) {
          // 在 API 29+ 上,我们可以直接注册正确的生命周期回调
          LifecycleCallbacks.registerIn(activity);
      }
    /**
    在 API 29 之前并保持与旧版本的 ProcessLifecycleOwner 的兼容性
    (更新生命周期运行时可能不会更新,并且需要支持不从支持 lib 扩展的 FragmentActivity 的活动)
    ,使用框架片段来获得正确的生命周期事件的时间安排
    */
      android.app.FragmentManager manager = activity.getFragmentManager();
      if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
          manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
          // Hopefully, we are the first to make a transaction.
          manager.executePendingTransactions();
      }
  }

最终调用的是dispatch()

@SuppressWarnings("deprecation")
    static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }

handleLifecycleEvent是属于LifecycleRegistry,那么终于都连起来了,
进入到handleLifeCycleEvent中

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
       enforceMainThreadIfNeeded("handleLifecycleEvent");
       moveToState(event.getTargetState());
   }

//进行状态转移
private void moveToState(State next) {
       if (mState == next) {
           return;
       }
       mState = next;
       if (mHandlingEvent || mAddingObserverCounter != 0) {
           mNewEventOccurred = true;
           // we will figure out what to do on upper level.
           return;
       }
       mHandlingEvent = true;
       //同步所有观察者,并进行事件分发
       sync();
       mHandlingEvent = false;
   }

5.怎么解决LiveData的黏性事件

粘性事件的定义是什么?
即发射的事件如果早于注册,那么注册之后依然可以接收到的事件称为粘性事件,举个栗子,比如我在2022年订阅了一份广州日报,但是你还给我推送2019年的报纸,那就不厚道了,参考了博主我星空的文章:http://t.csdn.cn/w35CO看下源码,主要的原因是

  @SuppressWarnings("unchecked")
    private void considerNotify(ObserverWrapper observer) {
    //1
        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.
        //2
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
         //一般事件流程 :new Observe(mVersion=-1)-> 注册观察者(mLastVersion=-1)-> setValue(mVersion++) 
        //粘性事件的流程 :new Observe(mVersion=-1)-> setValue(mVersion++) ->注册观察者(mLastVersion=-1)
        //此时 mLastVersion=-1 , mVersion=0 ,未触发拦截导致首次注册时会触发接口回调造成粘性事件
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

解决方法是第一次进行拦截,不让livedate进行事件分发,注释1 和注释2 处的代码涉及到Framework层的代码,不好动,只能在第mLaseVersion 和mVersion上动手脚,在注册观察者时,通过反射修改mLastVersion的值,使得mLastVersion 和mVersion的值相等,那么就可以直接返回,不进行事件分发

class NonStickyMutableLiveData<T> : MutableLiveData<T>() {
    private var stickFlag = true
    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
        super.observe(owner, observer)
        if (stickFlag) {
            hook(observer)
        }
    }

    private fun hook(observer: Observer<in T>) {
        try {
            val liveDataClass = LiveData::class.java
            val mObserversField = liveDataClass.getDeclaredField("mObservers")
            mObserversField.isAccessible = true
            val mObserversObject = mObserversField[this]

            //得到map对应的class对象
            val mObserversClass: Class<*> = mObserversObject.javaClass
            //获取到mObserversClass对象的get()
            val get = mObserversClass.getDeclaredMethod("get", Any::class.java)
            get.isAccessible = true
            //执行get方法
            val invokeEntry = get.invoke(mObserversObject, observer)
            //定义一个空对象
            var observerWrapper: Any? = null
            if (invokeEntry != null && invokeEntry is Map.Entry<*, *>) {
                observerWrapper = invokeEntry.value
            }
            if (observerWrapper == null) {
                throw NullPointerException("observerWrapper is null")
            }
            //得到ObserverWrapper的类对象,编译擦除问题会引起多态冲突所以用getSuperClass
            val superClass: Class<*> = observerWrapper.javaClass.superclass
            val mLastVersion = superClass.getDeclaredField("mLastVersion")
            mLastVersion.isAccessible = true
            //得到mversion
            val mVersion = liveDataClass.getDeclaredField("mVersion")
            mVersion.isAccessible = true
            //将mVersion的值填入到mLastVersion
            val mVersionValue = mVersion[this]
            mLastVersion[observerWrapper] = mVersionValue
            stickFlag = false
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值