LiveData常用方法源码分析

2023-12-26 04:08

本文主要是介绍LiveData常用方法源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、postValue
protected void postValue(T value) {boolean postTask;// 同步锁synchronized (mDataLock) {// 判断mPendingData是否为NOT_SETpostTask = mPendingData == NOT_SET;// 对mPendingData赋值mPendingData = value;}// 防止数据重复设置if (!postTask) {return;}// 将数据发送到主线程处理ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}

步骤分解:

  • 1、LiveData通过postValue方法在子线程同步方法中设置数据
  • 2、数据NOT_SET校验
  • 3、将数据发送到主线程进行处理
2、setValue
 @MainThreadprotected void setValue(T value) {assertMainThread("setValue"); // 1mVersion++; // 2mData = value; // 3dispatchingValue(null); // 4}

步骤分解:

  • 1、主线程校验
  • 2、计数器自加
  • 3、为mData赋值
  • 4、分发数据(详见dispatchingValue)
3、assertMainThread 主线程校验
 static void assertMainThread(String methodName) {if (!ArchTaskExecutor.getInstance().isMainThread()) {throw new IllegalStateException("Cannot invoke " + methodName + " on a background"+ " thread");}}
4、dispatchingValue
   void dispatchingValue(@Nullable ObserverWrapper initiator) {// 1if (mDispatchingValue) {mDispatchInvalidated = true;return;}// 2mDispatchingValue = true;do {mDispatchInvalidated = false;// 3if (initiator != null) {considerNotify(initiator);initiator = null;} else {// 4for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}

步骤分解:

  • 1、分发状态标记,防止重复分发
  • 2、修改分发状态
  • 3、分发通过参数传递进来的迭代器中数据
  • 4、将数据分发给所有观察者
5、considerNotify
 private void considerNotify(ObserverWrapper observer) {// 1if (!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.// 2if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}// 3if (observer.mLastVersion >= mVersion) {return;}// 4observer.mLastVersion = mVersion;// 5observer.mObserver.onChanged((T) mData);}

步骤分解

  • 1、观察者非active状态,拦截
  • 2、通过shouldBeActive修改观察者active状态
  • 3、version计数器比对
  • 4、调用onChange方法,分发数据
6、observe
  @MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");// 1if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}// 2LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);// 3ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);// 4if (existing != null && !existing.isAttachedTo(owner)) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}// 5owner.getLifecycle().addObserver(wrapper);}

步骤分解

  • 1、如果owner为DESTROYED状态,直接return
  • 2、构造LifecycleBoundObserver
  • 3、构造ObserverWrapper(详见putIfAbsent)
  • 4、对已经存在观察者抛出异常,防止重复添加监听
  • 5、添加合法观察者
7、putIfAbsent
  public V putIfAbsent(@NonNull K key, @NonNull V v) {Entry<K, V> entry = get(key);if (entry != null) {return entry.mValue;}put(key, v);return null;}
  • Entry形式存储K、V值,K不允许重复
8、map
 public static <X, Y> LiveData<Y> map(@NonNull LiveData<X> source,@NonNull final Function<X, Y> mapFunction) {// 1final MediatorLiveData<Y> result = new MediatorLiveData<>();// 2result.addSource(source, new Observer<X>() {@Overridepublic void onChanged(@Nullable X x) {// 3result.setValue(mapFunction.apply(x));}});// 4return result;}

步骤分解

  • 1、创建MediatorLiveData
  • 2、通过addSource将源数据添加到result中
  • 3、为result添加源数据监听,并在接收到监听后setValue
  • 4、返回MediatorLiveData类型数据作为result
9、switchMap
 @MainThread@NonNullpublic static <X, Y> LiveData<Y> switchMap(@NonNull LiveData<X> source,@NonNull final Function<X, LiveData<Y>> switchMapFunction) {// 1final MediatorLiveData<Y> result = new MediatorLiveData<>();// 2result.addSource(source, new Observer<X>() {LiveData<Y> mSource;@Overridepublic void onChanged(@Nullable X x) {// 3LiveData<Y> newLiveData = switchMapFunction.apply(x);// 4if (mSource == newLiveData) {return;}// 5if (mSource != null) {result.removeSource(mSource);}// 6mSource = newLiveData;// 7if (mSource != null) {result.addSource(mSource, new Observer<Y>() {@Overridepublic void onChanged(@Nullable Y y) {// 8result.setValue(y);}});}}});// 9return result;}

步骤分解

  • 1、创建MediatorLiveData类型result
  • 2、将源数据添加到result中
  • 3、通过switchMapFunction的apply函数创建LiveData类型数据newLiveData
  • 4、与前一次的数据相同,直接返回
  • 5、数据不为空,通过removeSource方法将数据从result中移除
  • 6、缓存newLiveData至mSource
  • 7、mSource不为空,将mSource作为源数据添加到result中
  • 8、为result添加源数据mSource监听,并在接收到监听后setValue
  • 9、返回MediatorLiveData类型数据result
10、addSource
 @MainThreadpublic <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {// 1Source<S> e = new Source<>(source, onChanged);// 2Source<?> existing = mSources.putIfAbsent(source, e);// 3if (existing != null && existing.mObserver != onChanged) {throw new IllegalArgumentException("This source was already added with the different observer");}// 4if (existing != null) {return;}// 5if (hasActiveObservers()) {e.plug(); // 6}}

步骤分解

  • 1、以source和onChanged构造Source类型数据e
  • 2、以源数据source和e构造新的Source类型数据existing
  • 3、如果existing数据存在,也就是说之前已经为source添加过观察者情况,抛异常
  • 4、重复判断existing,进行返回
  • 5、如果有active的Observers,添加监听
  • 6、plug方法(详见plug)
11、plug() MediatorLiveData中
 void plug() {mLiveData.observeForever(this);}
  • observeForever
  /*** Adds the given observer to the observers list. This call is similar to* {@link LiveData#observe(LifecycleOwner, Observer)} with a LifecycleOwner, which* is always active. This means that the given observer will receive all events and will never* be automatically removed. You should manually call {@link #removeObserver(Observer)} to stop* observing this LiveData.* While LiveData has one of such observers, it will be considered* as active.* <p>* If the observer was already added with an owner to this LiveData, LiveData throws an* {@link IllegalArgumentException}.** @param observer The observer that will receive the events*/@MainThreadpublic void observeForever(@NonNull Observer<? super T> observer) {assertMainThread("observeForever");// 1AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);// 2ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);// 3if (existing instanceof LiveData.LifecycleBoundObserver) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}// 4wrapper.activeStateChanged(true);}
  • 1、 通过observer构造AlwaysActiveObserver
  • 2、 通过observer和wrapper构造ObserverWrapper类型数据existing
  • 3、 如果existing数据已经存在,也就是说LiveData已经添加过该observer了,抛出异常
  • 4、修改wrapper的active状态为true

这篇关于LiveData常用方法源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538038

相关文章

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Git中恢复已删除分支的几种方法

《Git中恢复已删除分支的几种方法》:本文主要介绍在Git中恢复已删除分支的几种方法,包括查找提交记录、恢复分支、推送恢复的分支等步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录1. 恢复本地删除的分支场景方法2. 恢复远程删除的分支场景方法3. 恢复未推送的本地删除分支场景方法4. 恢复

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处

Window Server2016加入AD域的方法步骤

《WindowServer2016加入AD域的方法步骤》:本文主要介绍WindowServer2016加入AD域的方法步骤,包括配置DNS、检测ping通、更改计算机域、输入账号密码、重启服务... 目录一、 准备条件二、配置ServerB加入ServerA的AD域(test.ly)三、查看加入AD域后的变

Window Server2016 AD域的创建的方法步骤

《WindowServer2016AD域的创建的方法步骤》本文主要介绍了WindowServer2016AD域的创建的方法步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、准备条件二、在ServerA服务器中常见AD域管理器:三、创建AD域,域地址为“test.ly”

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu