当前位置:网站首页>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 .
边栏推荐
- Tree drop-down selection box El select combined with El tree effect demo (sorting)
- uva11825
- Some thoughts on port forwarding program
- [QNX Hypervisor 2.2用户手册]6.2.1 Guest之间通信
- Daily question 1 - force deduction - there are three consecutive arrays of odd numbers
- 多模态 —— Learnable pooling with Context Gating for video classification
- QT qframe details
- About DDNS
- Json tobean
- uva10635
猜你喜欢

idea使用

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

Redis of NoSQL database (I): Installation & Introduction

微信小程序学习笔记(暑假)

QT qframe details

Uniapp obtains the date implementation of the beginning and end of the previous month and the next month

Qt QFrame详解

Idea use

Two methods for preorder traversal of binary tree

JVM系列之对象深度探秘
随机推荐
[translation] [Chapter II ①] mindshare PCI Express technology 3.0
package. Are you familiar with all configuration items and their usage of JSON
Save token get token refresh token send header header
Li Kou daily question - day 30 -594 Longest harmonic subsequence
把多个ROC曲线画在一张图上
Method of changing host name (permanent)
The realization of changing pop-up background at any time
Json对象和Json字符串的区别
[when OSPF introduces direct connection routes, it makes a summary by using static black hole routes]
jetson tx2
CI工具Jenkins之二:搭建一个简单的CI项目
Tree drop-down selection box El select combined with El tree effect demo (sorting)
利用IPv6实现公网访问远程桌面
Instanceklass "suggestions collection" of hotspot class model
Crawler data analysis (introduction 2-re analysis)
Chinese garbled code on idea console [valid through personal test]
LiveData源码赏析 —— 基本使用
WDCP accesses all paths that do not exist and jumps to the home page without returning 404
Summary of some new datasets proposed by cvpr2021
Message queue batch processing refund order through queue