当前位置:网站首页>Livedata source code appreciation - basic use
Livedata source code appreciation - basic use
2022-06-29 07:15:00 【Cattle within yards】
author : It's snowing in the evening _
Reprinted address :https://juejin.cn/post/7112991690914267143
LiveData Is an abstract class , We usually use MutableLiveData establish LiveData object .
public class MutableLiveData<T> extends LiveData<T> {}
MutableLiveData Just inherited LiveData, No additional operations .
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
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);
}
1. First assertMainThread() Method will first determine the current calling thread , If it is not in the main thread, an exception will be thrown
2. And then through owner obtain Lifecycle The current state , If it has been destroyed (DESTROYED), There is no point in registering an observer at this time , Direct to ignore .
3. take owner and observer Package as LifecycleBoundObserver object .
4. take observer As key,wrapper As value Stored in mObservers, If mObservers It didn't exist before observer,putIfAbsent() Method directly adds and returns null, If it already exists , It is still the original value , And return the old value .
5. If LiveData It has been held internally before observer Object and bound to other LifecycleOwner object , Throw an exception .
6. If you already have observer Object but bound to the same LifecycleOwner Object ignores this registration .
7. take wrapper Add to Lifecycle.
observe() method owner and observer Package as LifecycleBoundObserver object ,LifecycleBoundObserver Not only did it inherit ObserverWrapper abstract class , It's also achieved
LifecycleEventObserver Interface , and LifecycleEventObserver Actually inherited from LifecycleObserver Interface .
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
//...... Omitted code
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
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();
}
}
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver need LifecycleOwner In an active state , The life cycle is at least STARTED state , And it is bound to the life cycle , therefore detachObserver() Method needs to remove itself , When the life cycle changes, it will call back onStateChanged() Method , If Lifecycle Already in DESTROYED Status quo , Then take the initiative to remove mObserver, Otherwise, distribute the data according to the current status .
observeForever
observeForever() Method can register an unrelated LifecycleOwner Object's Observer. under these circumstances Observer Considered always active , Therefore, when there are data changes, they will always be notified .LiveData Will not actively remove these Observer, We need to actively call... At the right opportunity removeObserver() Method to remove .
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
- observeForever() Methods and observe() Methods must be called in the main thread .
- take observer Package as AlwaysActiveObserver object .
- If LiveData It has been held internally before observer Object and associated with LifecycleBoundObserver above , An exception will be thrown .
- call activeStateChanged() Method , Because the current LiveData It may have been set .
AlwaysActiveObserver It's also ObserverWrapper Subclasses of .
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
boolean shouldBeActive() {
return true;
}
}
And LifecycleBoundObserver The difference is shouldBeActive() Method returns fixed true, Indicates that it is always active . Whenever there is a data change, it will be recalled , So to avoid memory leaks and null pointer exceptions , We should not need Observer Remove it when .
removeObserver
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
removed.detachObserver();
removed.activeStateChanged(false);
}
- from map Remove Observer.
- Call the removed Observer Of detachObserver Method and state mActive Set as false.
ObserverWrapper
aforementioned LifecycleBoundObserver and AlwaysActiveObserver All are ObserverWrapper Subclasses of .
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
// Omitted code .....
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
ObserverWrapper Yes Observer Made a layer of packing , Added active status and version information , When the active state changes activeStateChanged() Method , He can count Observer Active number and in Observer Distribute data when active .
changeActiveCounter
@MainThread
void changeActiveCounter(int change) {
int previousActiveCount = mActiveCount;
mActiveCount += change;
if (mChangingActiveState) {
return;
}
mChangingActiveState = true;
try {
while (previousActiveCount != mActiveCount) {
boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
previousActiveCount = mActiveCount;
if (needToCallActive) {
onActive();
} else if (needToCallInactive) {
onInactive();
}
}
} finally {
mChangingActiveState = false;
}
}
changeActiveCounter() Method to change the current active state observe Number , Then judge if the number of active states is determined from 0 To 1 Called onActive Method , The number of active states is determined by 1 To 0 Called onInactive Method . Both methods are empty implementations , need LiveData Subclasses of implement as needed . Add while It is to prevent during execution changeActiveCounter() Method is called , Lead to mActiveCount Be updated .
边栏推荐
- Crawler data analysis (introduction 2-re analysis)
- Redis of NoSQL database (II): introduction to redis configuration file
- IDEA 集成 码云
- What are the conditions for a high-quality public chain?
- YGG pilipinas: typhoon Odette disaster relief work update
- Multimodal learning pooling with context gating for video classification
- [answer all questions] CSDN question and answer function evaluation
- NoSQL数据库之Redis(四):Redis新数据类型
- 消息队列之通过幂等设计和原子锁避免重复退款
- Why should enterprises do more application activities?
猜你喜欢

NoSQL数据库之Redis(四):Redis新数据类型

Suggestions on digital transformation of large chemical enterprises

In vscade, how to use eslint to lint and format

【软件测试】接口——基本测试流程

IDEA 集成 码云

树形下拉选择框el-select结合el-tree效果demo(整理)

Move disassembly of exclusive delivery of script (the first time)

Database - Synonyms

通过keyup监听textarea输入更改按钮样式

json tobean
随机推荐
微信小程序学习笔记(暑假)
【翻译】簇拥而出。构建现代应用程序的设计方法
[translation] [Chapter 2 ③] mindshare PCI Express technology 3.0
LeetCode_动态规划_中等_91. 解码方法
Common status codes for page error reporting
国内代码托管中心- 码云
Unexpected exception ... code: Badrequest when downloading Xilinx 2018.2
消息队列之通过队列批处理退款订单
JDBC connects to the database and socket sends the client.
Introduction to Ceres Quartet
NoSQL数据库之Redis(二):Redis配置文件介绍
Unity ar shadow shadow
About DDNS
QT serial port programming
Li Kou daily question - day 30 -594 Longest harmonic subsequence
Tree drop-down selection box El select combined with El tree effect demo (sorting)
Exclusive download. Alibaba cloud native brings 10+ technical experts to bring new possibilities of cloud native and cloud future
开源二三事|ShardingSphere 与 Database Mesh 之间不得不说的那些事
try anbox (by quqi99)
And check the collection hello