当前位置:网站首页>LiveData源码赏析 —— 基本使用
LiveData源码赏析 —— 基本使用
2022-06-29 06:38:00 【码中之牛】
作者:晚来天欲雪_
转载地址:https://juejin.cn/post/7112991690914267143
LiveData是一个抽象类,我们一般使用MutableLiveData创建LiveData对象。
public class MutableLiveData<T> extends LiveData<T> {}
MutableLiveData仅仅继承了LiveData,没有做其他额外的操作。
@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.首先assertMainThread()方法会先判断当前调用线程,如果不在主线程则会抛出异常
2.然后通过owner获取Lifecycle当前所处于的状态,如果已经销毁(DESTROYED),则此时注册观察者毫无意义,直接忽略。
3.将owner和observer包装成LifecycleBoundObserver对象。
4.将observer作为key,wrapper作为value存储在mObservers,如果mObservers之前不存在observer,putIfAbsent()方法直接添加并返回null,如果已经存在,则依旧为原来的值,并返回旧的值。
5.如果LiveData内部之前已经持有了observer对象并且绑定了其他LifecycleOwner对象,则抛出异常。
6.如果已经持有observer对象但是绑定的是同一个LifecycleOwner对象则忽略此次注册。
7.将wrapper添加到Lifecycle。
observe()方法中将owner和observer包装成LifecycleBoundObserver对象,LifecycleBoundObserver不仅继承了ObserverWrapper抽象类,还实现了
LifecycleEventObserver接口,而LifecycleEventObserver实际继承于LifecycleObserver接口。
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
//......省略部分代码
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需要LifecycleOwner处于活跃状态,生命周期至少是STARTED状态,而且它是与生命周期绑定的,所以detachObserver()方法中需要将自己移除,当生命周期变化的时候会回调onStateChanged()方法,如果Lifecycle已经处于DESTROYED状态了,则主动移除mObserver,否则根据当前状态分发数据。
observeForever
observeForever()方法可以注册一个没有关联LifecycleOwner对象的Observer。在这种情况下Observer被认为始终处于活动状态,因此当有数据变化时总是会被通知。LiveData不会主动移除这些Observer,需要我们在合适的机会主动调用removeObserver()方法进行移除。
@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()方法和observe()方法一样都必须在主线程调用。
- 将observer包装成AlwaysActiveObserver对象。
- 如果LiveData内部之前已经持有了observer对象并且关联在LifecycleBoundObserver上面,则会抛出异常。
- 调用activeStateChanged()方法,因为当前 LiveData 可能已经被设置值了。
AlwaysActiveObserver也是ObserverWrapper的子类。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
boolean shouldBeActive() {
return true;
}
}
与LifecycleBoundObserver不同的是shouldBeActive()方法固定返回true,表明它一直是活跃状态。只要有数据变化都会进行回调,所以为了避免内存泄漏和空指针异常,我们应该在不需要Observer的时候将它移除。
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);
}
- 从map中移除Observer。
- 调用被移除的Observer的detachObserver方法并且把状态mActive置为false。
ObserverWrapper
前面提到的LifecycleBoundObserver和AlwaysActiveObserver都是ObserverWrapper的子类。
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
//省略部分代码.....
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
ObserverWrapper对Observer做了一层包装,加入了活跃状态和版本信息,当活跃状态改变的时候会调用activeStateChanged()方法,他会统计Observer活跃数并且在Observer活跃的时候分发数据。
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()方法改变当前激活状态的observe数量,然后判断如果激活状态得数量由从0到1调用了onActive方法,激活状态数量由1到0调用了onInactive方法。这两个方法都是空实现,需要LiveData的子类按需要实现。加while是为了防止在执行过程中changeActiveCounter()方法被调用,导致mActiveCount被更新。
边栏推荐
- Analytic hierarchy process
- Configuring the flutter development environment
- Qt foreach关键字
- JDBC连接数据库,socket发送客户端。
- Introduction to NoSQL database
- Idea integrated code cloud
- Solve the problem that NPM does not have permission
- Message queue avoiding repeated refund by idempotent design and atomic lock
- 施工企业选择智慧工地的有效方法
- 数据库-同义词
猜你喜欢

Effective methods for construction enterprises to select smart construction sites

It is the only one in China that Alibaba cloud container service has entered the Forrester leader quadrant

The realization of changing pop-up background at any time

Analytic hierarchy process

Introduction to NoSQL database

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

JVM系列之对象深度探秘

Redis of NoSQL database (I): Installation & Introduction

And check the collection hello

QT serial port programming
随机推荐
Mongostat performance analysis
示波器 符号
Ci tools Jenkins installation configuration tutorial
Ci tool Jenkins II: build a simple CI project
What is the difference between software engineer and software development? What is the difference between software engineer and software developer?
Exploring the depth of objects in JVM series
YGG cooperated with Web3 platform leader to empower the creative community with Dao tools and resources
Database - Synonyms
把多个ROC曲线画在一张图上
Introduction to NoSQL database
Better than postman! Apipost knows more about Chinese programmers! How delicious!
Json对象和Json字符串的区别
[translation] [Chapter II ①] mindshare PCI Express technology 3.0
Suggestions on digital transformation of large chemical enterprises
Character pointer as function parameter
Shift/space studio "Aurora" project: building a villa in the sandbox metauniverse
Idea use
json tobean
国内代码托管中心- 码云
Redis (4) of NoSQL database: redis new data type