当前位置:网站首页>Read livedata sticky events
Read livedata sticky events
2022-06-22 01:23:00 【Silent Pinot trough】
Article to read LiveData The sticky events of
Preface
Put it in a more general way , Is to send data first , Post subscription , Data can also be received .
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-klZR6QTN-1655823049309)(/Users/wyl/Documents/ Blog / article / picture /tutieshi_640x360_2s.gif)]](/img/99/762111e33a501b78a4c1b56cd09d1f.png)
This is actually livedata A feature of , However, it has brought great inconvenience to our daily use , And it doesn't provide API To remove sticky events , This is really not very friendly .
Next , Just bring us to uncover the secret LiveData Principle of viscous event .
A lot of source code is coming from the front , In case of any discomfort , You can jump directly to the summary .
principle
First we start by sending a message
liveData.postValue(" page 1 Message sent ")
There are two ways to send messages :setValue and postValue
setValue Can only be used on the main thread ,postValue Can be used in any thread , When it is called , adopt handler Switch to the main thread , Call again setValue
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
Here is a mVersion Pay attention to , We'll use that later . And then through dispatchingValue Method to distribute messages .
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
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;
}
In this way , It is mainly about whether the observer of parameter transmission is empty , If it's not empty , Then distribute the message to this observer , If it is empty , The observer will be traversed from the observer set , distributed . ad locum , We mainly look at considerNotify Method .
private void considerNotify(ObserverWrapper observer) {
...............
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
We mentioned earlier mVersion It's used here , and mLastVersion Made a comparison , We will explain this in the next step .
This is the whole process of sending messages , It's very simple , But it's not enough to see the whole picture , Next we analyze another step , monitor .
liveData.observe(this) {
Log.e("TAG", "onCreate: ")
tv.setText(" Monitored messages :$it")
}
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
............
owner.getLifecycle().addObserver(wrapper);
}
ad locum , Mainly for our owner and observer Made a layer of packing , And then let lifecycle It was monitored . Then we'll see What's packed
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
.........
@Override
public 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());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
............
}
You can see LifecycleBoundObserver Inherited ObserverWrapper , Realized LifecycleEventObserver Interface .
LifecycleEventObserver Interface Mainly when lifecycle When the state changes, it will sense , And call back .
Then we mainly look at the parent class ObserverWrapper :
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
............
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
Did you see a familiar face , This is our last step Mentioned mLastVersion , It is defined here , And the default is -1; This will be run through later , First understand its source .
Next , Let's continue the process first , still LifecycleBoundObserver Class , When the state changes , Would call onStateChanged Method
@Override
public 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());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
When the active state changes , Meeting call activeStateChanged :
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
When the state is active , Would call dispatchingValue Data distribution , The distribution we used above is to traverse all observers for data distribution , This time, only the current observer will be distributed .
summary
Next, let's continue :
First send the data postValue , The number of times will make mVersion++ operation , Then traverse the observer for distribution .
Then listen , While listening , Will use LifecycleBoundObserver Pack the observer , In this operation ,LifecycleBoundObserver Parent class of ObserverWrapper Defined mLastVersion by -1 . When the data is finally distributed ,mLastVersion Less than mVersion Of , So it was not intercepted , Then the data is distributed .
And then there's the sticky event .

There are many solutions for sticky events now , I won't elaborate here , You can refer to this article :
https://www.jianshu.com/p/d0244c4c7cc9
边栏推荐
- 4274. 后缀表达式
- Special survey of moving average strategy
- matplotlib 制作不等间距直方图
- Idea prompt duplicated code fragment (15 lines long)
- Judge whether the string type is empty and whether the list set is empty
- 判断String类型是否为空,判断list集合是否为空
- Tensorflow环境搭建
- 2. add two numbers
- 4g/wifi energy consumption metering socket - monitoring voltage, current and power
- Install easyx-vc2019
猜你喜欢

Pytorch learning 04: creation of tensor

Pytorch learning 05: indexing and slicing
![3 minutes, take you to play with chat robot automation [top template]](/img/71/4d848b46a52b71a351a086db248a95.png)
3 minutes, take you to play with chat robot automation [top template]

Example and description of lvgl Demo 1

4G/wifi 能耗计量插座-监测电压电流功率

Graphical understanding of the article "text classification of Sina News Based on tensorflow+rnn"

How to remove duplication in left join from a simple example

Tensorflow环境搭建

Want to join a big factory? Reading this article may help you

03 fastjson resolving circular references
随机推荐
==And equals
Shardingsphere-proxy-5.0.0 implementation of distributed hash modulo fragmentation (4)
【Redis】ubuntu中安装redis以及redis的基本使用和配置
3371. 舒适的奶牛
[redis] install redis in Ubuntu and the basic usage and configuration of redis
[dailyfresh] course record 2
03 FastJson 解决循环引用
手写数据库连接池
[其他] 浅析ELF中的GOT与PLT
[glib][gstreamer] plug in writing ideas -- inheritance, override and virtual functions
yolov3 3D 语义点云paper阅读
. Several methods of obtaining hinstance in. Net
Difference between MSVC and GCC (under collection)
[project construction] cmake create release and debug projects
Compilation principle - recursive descent subroutine method
RNN的简单整理
The appearance, space, safety and power are all upgraded. The xinjietu x70s will be put on the market from 87900 yuan
BigDecimal基本使用
【DailyFresh】发送激活邮件遇到的问题
IDEA 提示 Duplicated code fragment (15 lines long)