当前位置:网站首页>Andriod --- JetPack :LiveData setValue 和 postValue 的区别
Andriod --- JetPack :LiveData setValue 和 postValue 的区别
2022-07-07 12:48:00 【梁同学与Android】
文章内容来自:https://blog.csdn.net/catzifeng/article/details/103931517
Andriod — JetPack :LifeCycle 的诞生
Andriod — JetPack :ViewModel 的诞生
Andriod — JetPack :BaseObservable 与 ObservableField 双向绑定
Andriod — JetPack :DataBinding + LiveData +ViewModel 简单实例
Andriod — JetPack :Room + ViewModel + LiveData 增删改查实例
Andriod — JetPack :LiveData setValue 和 postValue 的区别
平时我们使用LiveData的时候,需要更新数据的时候,LiveData提供了两种更新数据的方式:
- setValue(T value)
- postValue(T value)
那么这两种方式有什么区别呢?
结论
setValue()只能在主线程中调用,postValue()可以在任何线程中调用。
setValue()
我们先不急着看源码,先看官方如何介绍这个方法。
/** * Sets the value. If there are active observers, the value will be dispatched to them. * <p> * This method must be called from the main thread. If you need set a value from a background * thread, you can use {@link #postValue(Object)} * * @param value The new value */
@MainThread
protected void setValue(T value)
上面的注释已经很清楚了:
这个方法必须在主线程中调用,如果你需要在后台线程中设置value,请移步 #postValue(Object)
更何况人家还用了一个 @MainThread的注解提醒你呢,接下来看源码:
protected void setValue(T value) {
assertMainThread("setValue"); //1
mVersion++; //2
mData = value; //3
dispatchingValue(null); //4
}
private static void assertMainThread(String methodName) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " thread");
}
}
首先调用 assertMainThread() 方法来判断当前线程是否为主线程(这里他通过一个ArchTaskExecutor的单例类来实现),如果不是主线程,直接抛异常提醒程序员。
如果是在主线程中调用该方法,自加加一个version,来说明值发生了变化。
再把新的值保存起来。
更新value(这个方法不能扯下去,扯下去就是LiveData的源码分析了)。
postValue
我们继续先看一下官方对postValue()的介绍:
/** * Posts a task to a main thread to set the given value. So if you have a following code * executed in the main thread: * <pre class="prettyprint"> * liveData.postValue("a"); * liveData.setValue("b"); * </pre> * The value "b" would be set at first and later the main thread would override it with * the value "a". * <p> * If you called this method multiple times before a main thread executed a posted task, only * the last value would be dispatched. * * @param value The new value */
protected void postValue(T value)
翻译过来就是:
通过任务(Runnable)的方式在主线程中更新数据。
如果同时调用 .postValue(“a”)和.setValue(“b”),一定是值b被值a覆盖。
如果多次调用 .postValue(),只有最后一个值能够被分发(onChanged()被调用)。
再看详细的源码:
protected void postValue(T value) {
boolean postTask; //1
synchronized (mDataLock) {
//2
postTask = mPendingData == NOT_SET; //3
mPendingData = value; //3
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); //4
}
定义一个 postTask 的布尔值,判断是否要更新。
加个同步锁,因为可能存在多个子线程同时调用 .postValue() 的情况。
通过判断更新的值是否发生变化来对postTask赋值,并且将value赋值给 mPendingData(mPendingData == NOT_SET第一次一定是返回true,之后都是返回false,然后到这个值更新完毕之前的一瞬间会调用mPendingData=NOT_SET,这也是为什么多次调用 postValue()只有最后一个值才有效的原因)。
通过ArchTaskExecutor进行更新,通过方法及参数名字,我们可以猜测这一步干了什么事情:ArchTaskExecutor将一个Runnable对象往主线程里执行,那么mPostValueRunnable执行的环境一定是主线程,接下来我们再看看mPostValueRunnable究竟做了些什么。
因为现在线程已经切换到主线程了,所以他直接就是调用 setValue()
最后
文中有几次出现了ArchTaskExecutor这个东西,这个类其实就是postValue切换至主线程更新的关键它具体的源码实现非常简单,直接是利用了Handler的机制。
边栏推荐
- 电脑Win7系统桌面图标太大怎么调小
- In the field of software engineering, we have been doing scientific research for ten years!
- JSON parsing instance (QT including source code)
- JS in the browser Base64, URL, blob mutual conversion
- Es log error appreciation -- allow delete
- JS image to Base64
- Half an hour of hands-on practice of "live broadcast Lianmai construction", college students' resume of technical posts plus points get!
- 找到自己的价值
- Substance Painter筆記:多顯示器且多分辨率顯示器時的設置
- Shengteng experience officer Episode 5 notes I
猜你喜欢

全球首款 RISC-V 笔记本电脑开启预售,专为元宇宙而生!

智汀不用Home Assistant让小米智能家居接入HomeKit

Instructions for mictr01 tester vibrating string acquisition module development kit

Computer win7 system desktop icon is too large, how to turn it down

大厂做开源的五大痛点

Five pain points for big companies to open source

潘多拉 IOT 开发板学习(HAL 库)—— 实验12 RTC实时时钟实验(学习笔记)

多商戶商城系統功能拆解01講-產品架構

Cocoscreator operates spine for animation fusion

AWS学习笔记(三)
随机推荐
Novel Slot Detection: A Benchmark for Discovering Unknown Slot Types in the Dialogue System
Simple use of websocket
安恒堡垒机如何启用Radius双因素/双因子(2FA)身份认证
MicTR01 Tester 振弦采集模塊開發套件使用說明
A laravel background management expansion package you can't miss - Voyager
小程序目录结构
今日睡眠质量记录78分
Discussion on CPU and chiplet Technology
"July 2022" Wukong editor update record
Full details of efficientnet model
防火墙基础之服务器区的防护策略
The method of parsing PHP to jump out of the loop and the difference between continue, break and exit
PyTorch模型训练实战技巧,突破速度瓶颈
Five pain points for big companies to open source
寺岗电子称修改IP简易步骤
The world's first risc-v notebook computer is on pre-sale, which is designed for the meta universe!
Substance painter notes: settings for multi display and multi-resolution displays
MicTR01 Tester 振弦采集模块开发套件使用说明
PD virtual machine tutorial: how to set the available shortcut keys in the parallelsdesktop virtual machine?
Leetcode - Sword finger offer 05 Replace spaces