当前位置: 首页> 娱乐> 八卦 > 高端衣服网购平台_免费网站设计什么价格_个人博客网站模板_上海高玩seo

高端衣服网购平台_免费网站设计什么价格_个人博客网站模板_上海高玩seo

时间:2025/7/9 19:46:06来源:https://blog.csdn.net/WPR13005655989/article/details/144498823 浏览次数:0次
高端衣服网购平台_免费网站设计什么价格_个人博客网站模板_上海高玩seo

LiveData 源码分析

前言

用过MVVM的大概知道LiveData可以感知组件的生命周期,当页面活跃时,更新页面数据,
当页面处于非活跃状态,它又会暂停更新,还能自动注册和注销观测者,能有效避免内存泄漏和不必要的更新。
那它是怎么做到这么’聪明‘的呢?下面通过两种情况(生命周期变化和主动修改数据)分析源码逐一分析。

一、生命周期变化,更新UI

viewModel.data.observe(this) {//xxx
}

当我们执行如上代码时,会发生什么呢?

观察者 observer


@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");if (owner.getLifecycle().getCurrentState() == DESTROYED) {//如果当前组件的生命周期处于销毁状态,就不会订阅成功// ignorereturn;}LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//已经存在并且已经被附加到相同的`owner`会抛异常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);
}

可以发现,里面创建了一个LifecycleBoundObserver对象,LifecycleBoundObserver 继承自ObserverWrapper
,而ObserverWrapper
是一个抽象类,它主要功能是定义一个通知订阅者更新UI的逻辑结构,具体实现在LifecycleBoundObserver
AlwaysActiveObserver。 下面详细看看它干了些啥事情

  1. LifecycleBoundObserver 源码
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {@Overrideboolean shouldBeActive() {//检查当前是否处于活跃状态return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@Overridepublic void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) {Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();if (currentState == DESTROYED) {//销毁状态,自动移除观测者removeObserver(mObserver);return;}Lifecycle.State prevState = null;while (prevState != currentState) {//状态发生变化prevState = currentState;activeStateChanged(shouldBeActive());//触发数据分发操作,通知UIcurrentState = mOwner.getLifecycle().getCurrentState();}}
}

LifecycleBoundObserver被订阅后,会被LifecycleOwner
管理,持续观测组件的生命周期,也就是说一旦生命周期变化后,会触发上面的onStateChanged,进而按需通知观察者刷新数据,
,这样就实现了感知组件的生命周期了。

  1. AlwaysActiveObserver字面意思,与上面不一样的是,1只在活跃状态通知,而它只要生命周期发生变化都通知不管什么状态

二、主动修改数据,触发更新UI

主动修改LiveData数据有两种方法,setValuepostValue,需要注意的是无论哪个函数,最终都是修改mData
的值,而mData的值又由dispatchingValue修改。

setValue


@MainThread
protected void setValue(T value) {assertMainThread("setValue");mVersion++;mData = value;dispatchingValue(null);
}

setValue做了主线程判断,必须在主线程调用,内部是立即更新数据并调用dispatchingValue通知观察者.

postValue

postValue则是跑了一个异步,把setValue操作添加到了主线程消息队列。

protected void postValue(T value) {boolean postTask;//是否需要通知UI刷新synchronized (mDataLock) {//NOT_SET 说明当前没有待更新的数据,可以进行刷新postTask = mPendingData == NOT_SET;//先把当前设置的数据放到待更新的位置mPendingData = value;}if (!postTask) {//只有在NOT_SET状态才发送setValue消息 return;}//把操作放到主线程队列,等待执行ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

再看看mPostValueRunnable源码

private final Runnable mPostValueRunnable = new Runnable() {@SuppressWarnings("unchecked")@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}setValue((T) newValue);}
};

postValue一次后,待修改数据变量mPendingDataNOT_SET
变为设置的数据,mPostValueRunnable被放到主线程队列,假如主线程队列比较空闲,mPostValueRunnable
马上被执行,也就是触发setValue函数。
这里可以引申出一个问题,假如主线程消息队列排得非常满,根本没空执行mPostValueRunnable
,此时频繁调用postValue,当轮到mPostValueRunnable执行时会不会按postValue顺序刷新UI呢

  • 上一张粗略的流程图
    ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/202307在这里插入图片描述
    24024159.png?origin_url=progress.png&pos_id=img-jYcd2nSV-1734314525716)
    可以看出,当短时间内频繁postValue,数据会不断被修改,但是在主线程消息队列中,只要有mPostValueRunnable
    未执行,那么mPendingData一直是非NOT_SET,所以消息队列中就只会出现一条mPostValueRunnable
    消息,其他都会被拦截,也就是说,就postValue了N次,最终刷新页面时,只会显示最终的数据

通知更新UI–》dispatchingValue

修改完数据,由dispatchingValue函数负责通知订阅者数据变化,看如下关键源码:

 void dispatchingValue(@Nullable ObserverWrapper initiator) {//***省略//considerNotify(...)
}private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;observer.mObserver.onChanged((T) mData);
}

如上源码,最终还是调用了observer.shouldBeActive
判断是否需要更新UI,而这个观察者正是上面提到的LifecycleBoundObserver,所以一样会根据当前是否在活跃状态判断是否需要通知UI

关键字:高端衣服网购平台_免费网站设计什么价格_个人博客网站模板_上海高玩seo

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: