当前位置:网站首页>Livedata source code appreciation III - frequently asked questions
Livedata source code appreciation III - frequently asked questions
2022-06-30 11:13:00 【Android daily lecture】
Data loss
adopt postValue() Method update LiveData Data time , There may be data loss .
val liveData = MutableLiveData()
Thread {
for (index in 0..9) {
liveData.postValue("new str $index")
}
}.start()
liveData.observe(this) {
Log.i("LiveData", "observe: $it")
}
We called... In succession postValue()10 Time , But the result is only the last data .
LiveData: observe: new str 10
This is because postValue() In fact, the logic of data callback is put into Runnable in , Again post to Handler, utilize Handler Update... In the main thread , So from postValue() To carry out Runnable, There is a time difference in the middle . In this period of time through postValue() Method update data will only change LiveData Internal value , Not again post A new Runnable.
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
Only when Runnable Carried out mPendingData Will be assigned to NOT_SET, In this way postValue() When it comes to execution postTask = mPendingData == NOT_SET To make postTask The value of is true, At the end of the day post One Runnable.
Viscous events
If the event launched is earlier than the registration , The events that can still be received after registration are called sticky events .
LiveData The inside is through an integer mVersion To record the version number of the current data .
protected void setValue(T value) {
// Omit other code
mVersion++;
}
When we call setValue() When updating data ,mVersion It's going to increase .
private abstract class ObserverWrapper {
int mLastVersion = -1;
}
In our observer's packaging class ObserverWrapper A version number is also maintained internally mLastVersion, It records the data version of the last callback , Initialize to -1.
If we change first LiveData The data of , that mVersion It will increase and become 1, Then register the observer , At this time, the version number maintained internally by the observer mLastVersion For the initial value -1. Finally, during the callback judgment (observer.mLastVersion >= mVersion) Will not be established , So the observer will receive the data before it is registered .
private void considerNotify(ObserverWrapper observer) {
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
Data processing
If you want to LiveData Change the value stored in the object before it is assigned to the observer , Or you need to return different values according to the value of another instance LiveData example , have access to Transformations Class LiveData Data processing of .
map
map Can be LiveData Internal data type conversion , send LiveData Convert to LiveData.
val intLiveData = MutableLiveData(1)
val strLiveData:LiveData<String> = Transformations.map(intLiveData){
"$it"
}
strLiveData.observe(this){
println(it is String)//true
}
switchMap
switchMap() According to a certain value , Switch and observe different LiveData data . It can also be realized LiveData Convert to LiveData.
val originLiveData = MutableLiveData(true)
val trueLiveData = MutableLiveData("trueLiveData")
val falseLiveData = MutableLiveData("falseLiveData")
val distinctLiveData = Transformations.switchMap(originLiveData) {
if (it) {
trueLiveData
} else {
falseLiveData
}
}
distinctLiveData.observeForever {Log.i(TAG, it)}//trueLiveData
distinctUntilChanged
distinctUntilChanged() Method returns a masked primitive LiveData New... Of duplicate data LiveData.
val boolLiveData = MutableLiveData<Boolean>()
val distinctLiveData = Transformations.distinctUntilChanged(boolLiveData)
Thread {
for (index in 0..10) {
SystemClock.sleep(100)
boolLiveData.postValue((index < 9))
}
}.start()
distinctLiveData.observe(this){
println(it) // As a result, the weight was removed Only true and false Two outputs
}
Perception life cycle
LiveData.observer() Methods can sense Owner Life cycle of , When this method is called, a LifecycleOwner object ,LifecycleOwner It's an interface .
public interface LifecycleOwner {
Lifecycle getLifecycle();
}
Fragment and FragmentActivity Both implement this interface and return a LifecycleRegistry object , When their life cycle changes , Would call LifecycleRegistry.handleLifecycleEvent() Method to distribute the lifecycle to the corresponding lifecycle observer . Callback LifecycleEventObserver Of onStateChanged() Method . and LifecycleBoundObserver Realized LifecycleEventObserver Interface , So he can receive the callback of life cycle change .
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
边栏推荐
- 国产自研系统的用户突破4亿,打破美国企业的垄断,谷歌后悔不迭
- SQL必需掌握的100个重要知识点:使用子查询
- Cp2112 teaching example of using USB to IIC communication
- 单片机 MCU 固件打包脚本软件
- Rejuvenated Dell and apple hit each other, and the two old PC enterprises declined rapidly
- LVGL 8.2 re-coloring
- 科普达人丨漫画图解什么是eRDMA?
- LVGL 8.2 Image
- The precision problem of depth texture in unity shader - stepping pit - BRP pipeline (there is no solution, it is recommended to replace URP)
- AMS源码解析
猜你喜欢
![[understanding of opportunity -34]: fate is within the light cone](/img/3e/9f5630ba382df7f7ce00705445cef8.jpg)
[understanding of opportunity -34]: fate is within the light cone

MySQL导出sql脚本文件

promise async和await的方法与使用

The jetpack compose dropdownmenu is displayed following the finger click position

【IC5000教程】-01-使用daqIDEA图形化debug调试C代码

【STL源码剖析】迭代器

从开源项目探讨“FPGA挖矿”的本质

Jetpack Compose DropdownMenu跟随手指点击位置显示

Retest the cloud native database performance: polardb is still the strongest, while tdsql-c and gaussdb have little change

List introduction
随机推荐
China will force a unified charging interface. If Apple does not bow its head, iPhone will be kicked out of the Chinese market
SQL必需掌握的100个重要知识点:插入数据
Rejuvenated Dell and apple hit each other, and the two old PC enterprises declined rapidly
What is erdma as illustrated by Coptic cartoon?
The two e-commerce bigwigs' lacy news screens represent the return of e-commerce to normal, which will be beneficial to the real economy
Time complexity and space complexity
LVGL 8.2 Checkboxes as radio buttons
SQL必需掌握的100个重要知识点:使用视图
Flutter 从零开始 004 按钮组件
考研这些“不靠谱”的经验有多害人?
LVGL 8.2 menu from a drop-down list
SQL必需掌握的100个重要知识点:使用子查询
LVGL 8.2 Drop down in four directions
LVGL 8.2 Image
记一次ViewPager + RecyclerView的内存泄漏
ArrayList与顺序表
LVGL 8.2 Checkboxes as radio buttons
The precision problem of depth texture in unity shader - stepping pit - BRP pipeline (there is no solution, it is recommended to replace URP)
14岁懂社会-《关于“工作的幸福”这件事儿》读书笔记
电商两位大佬花边新闻刷屏,代表电商回归正常,将有利于实体经济