Android Architecture Components 系列目录
博客创建时间:2021.01.25
博客更新时间:2020.01.26
以Android studio 4.1.1来分析讲解,gradle=6.5,SdkVersion 30。如图文和网上其他资料不一致,可能是别的资料版本较低而已
前言
** 本篇文章适合已能基本使用LiveData,但是具体原理和细节不太清楚的Android开发者。请跟随我的脚步一起探索LiveData的秘密!**
LiveData数据持有类。有如下特性点:
- 数据可以被观察者订阅
- 能够感知实现LifecycleOwner接口组件的生命周期(如Fragment、Activity、Service),减少内存泄漏。
- 可以设定组件处于激活状态(STARTED、RESUMED)才会通知观察者有数据更新,且组件前后台切换后能自动从最新数据开始刷新
原理
其实LiveData的原理非常简单,它的逻辑其实和设置点击监听事件是一样的,其步骤都是如下:
- 创建监听实例>>(MainThread中创建Observer)
- 对控件View设置监听>>(通过调用observe()或observeForever()对LiveData注册观察者)
- 发生点击事件>>(通过调用LiveData的setValue()或postValue()方法改变持有值T)
- 监听接口回调View.onClick()>>(LiveData进行数据的分发,最终调用Observer.onChanged()方法进行数据处理)
你能简单的通过Button的点击事件流程快速高效的理解LiveData的原理和调用流程,其实没有想象中的那么高大上。跟着我的脚步我们继续盘它!
属性
- mVersion
LiveData的标识版本,每次数据改动一次则mVersion++,它的作用用于判断T是否已经处理过,处理过的变动将不再做改动。
private int mVersion = START_VERSION;
- mPendingData
初始值为NOT_SET,它用于作为需要发射变动类型T的中介。当mPendingData ==NOT_SET时,LiveData处于数据准备状态;mPendingData !=NOT_SET,LiveData处于数据Set状态,不可继续Set值。
private volatile Object mData = NOT_SET;
volatile Object mPendingData = NOT_SET;
-
mObservers
一个LiveData可以注册多个Observe,现实使用情境为多个Actvity中可以注册监听同一个LiveData。mObservers 中保存的是Observer和其对应的包装类,根据Observer注册的方式不同,其ObserverWrapper也会不一样
@SuppressLint("RestrictedApi")
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
方法
1. observe(LifecycleOwner owner, Observer<? super T> observer)
注册具有生命周期监听的Observer,它可以安全地观察LiveData而不用担心泄漏,它的生命周期特性表现在
- 仅当owner处于Lifecycle.StateSTARTED或Lifecycle.StateRESUMED状态时,观察者才会收到事件。
- 如果owner处于 Lifecycle.StateDESTROYED状态,则observer将被自动删除。
- 在owner未激活的情况下更改数据时,它将不会收到任何更新。如果再次激活,它将自动接收最新的可用数据。(如Activity在onPause状态无法接收数据,变换为onRresume状态时可以接收数据)
- 如果Observer已注册过,但是在次注册时前后的owner不一致,则会抛IllegalArgumentException
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 判断是否在主线程,不在则抛异常
assertMainThread("observe");
// owner处于DESTROYED状态则无法进行Observer注册
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 从mObservers中获取LiveData.ObserverWrapper,如果不存在则返回null
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//如果Observer被注册过,但是owner前后不一致,则抛异常。
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//将wrapper加入observer的观察者列表
owner.getLifecycle().addObserver(wrapper);
}
2.observeForever(Observer<? super T> observer)
永久性注册方法,其特性为:
- 将给定的观察者添加到观察者列表中。此调用类似于带有生命周期所有者的{@link LiveData observe(LifecycleOwner,Observer)},该生命周期所有者始终处于活动状态。
- 给定的观察者将一直接收所有事件,并且永远不会被自动删除。除非手动调用removeObserver(Observer)方法停止
- 当LiveData具有此类观察者之一,则它将被视为active
- 如果在此之前已将观察者和所有者绑定的ObserverWrapper添加进入LiveData,此次在通过observeForever(Observer)方式注册观察者则抛IllegalArgumentException。
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
//是否在主线程中
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
//判断是否已在mObservers列表中
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 如果在此之前已将观察者和所有者绑定的ObserverWrapper添加进入LiveData,则抛IllegalArgumentException
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//设置wrapper更新为active=true
wrapper.activeStateChanged(true);
}
3.removeObserver(Observer<? super T> observer)
从观察者列表中删除给定的观察者,该方法应该与observeForever(Observer<? super T> observer)方法成对出现,它一般在onCreate和onDestory中调用
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
//observer原本就不存在于mObservers中
if (removed == null) {
return;
}
//如果ObserverWrapper含有owner,则将observer从owner的观察者列表中移除
removed.detachObserver();
//设置ObserverWrapper的active=false,状态改变为非激活状态
removed.activeStateChanged(false);
}
4.removeObservers(@NonNull final LifecycleOwner owner)
删除与给定的{@link LifecycleOwner}关联的所有观察者。
5. postValue(T value)
将任务发布到主线程以设置给定值。该方法可以在非UI线程中执行。如果在主线程执行发布的任务之前多次调用此方法,则只会分派最后一个值。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
// true:上一个数据已发送完毕,处于就绪状态
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
//上一个数据还未发送完毕,不可发布
return;
}
//在主线程中执行发布任务,修改设置
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
6. setValue(T value)
修改需要发射分发的值,每个值都有对应Version作为唯一id,此处mVersion++后进行值的发布。注意该方法只能运行在主线程中。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//修改mVersion,标识每个value
mVersion++;
mData = value;
dispatchingValue(null);
}
如果先后调用
- liveData.postValue(“a”);
- liveData.setValue(“b”);
首先将设置值“ b”,然后主线程将使用值“ a”覆盖它。
7. onActive()
当active Observer的数量从0变为1时调用
8. onInactive()
当active Observer的数量从1变为0时调用。此时并不意味着mObservers中不含Observer,有可能Observer的owner不处于StateSTARTED和StateRESUMED状态。
9. considerNotify(ObserverWrapper observer)
执行数据更新操作,通过多条件判断最终执行了我们熟悉的Observer.onChanged(T)。
private void considerNotify(ObserverWrapper observer) {
//确保ObserverWrapper是mActive=ture才能继续执行
if (!observer.mActive) {
return;
}
//确保当前生命周期处于允许状态,可继续执行后续代码
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//数据未发射处理过方可进行后续操作
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//进行数据刷新
observer.mObserver.onChanged((T) mData);
}
10. dispatchingValue(@Nullable ObserverWrapper initiator)
数据变更后的分发发射方法。当某一个ObserverWrapper第一次在LiveData中注册时,会自动发布最新的数据。所以要注意在Observer.onChanged(T)中做好NullPointerException预防
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
......
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;
}
}
}
......
}
内部类
在LiveData中有三个Observer包装类,ObserverWrapper、AlwaysActiveObserver和LifecycleBoundObserver,后两者是前者的子类。
在LiveData的两个两个注册方法中,其Observer有不同特性性很大的关系在于对应的Observer包装类不一样。
1. ObserverWrapper
AlwaysActiveObserver和LifecycleBoundObserver的父类,是一种带自定义属性的Observer包装类。
/**
* Observer包装类
*/
private abstract class ObserverWrapper {
//每个包装类都含有一个Observer
final Observer<? super T> mObserver;
// Observer活动状态active标识,只有处于活动状态的Observer,才能发射数据
boolean mActive;
// Observer的version标识
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
//是否应该处于Active
abstract boolean shouldBeActive();
/**
*是否Attached了owner
*/
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
/**
* 分离owner,需要子类中重写
*/
void detachObserver() {
}
/**
* active 激活状态的更改,条件达到会调用LiveData的onActive()和onInactive()方法
* 1.当newActive=true时,LiveData中的活跃数量mActiveCount由0变为1时,调用onActive(),同时发布值dispatchingValue(this)
* 2.当newActive=false时,LiveData中的活跃数量mActiveCount由1变为0时,调用onInactive()
*/
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
注意:
- boolean mActive是标识ObserverWrapper中的Observer是否可用,一般注册后就会变为true,移除后就会变为false。
- boolean shouldBeActive()是根据绑定的LifecycleOwner的指定生命周期股则来确定的,如果没有绑定LifecycleOwner则表明任意生命周期状态都为true。
2. AlwaysActiveObserver
重写了shouldBeActive()方法,保持AlwaysActiveObserver持有的Observer的活跃状态active始终为true。
AlwaysActiveObserver是observeForever(observer)方法中注册的指定ObserverWrapper。
/**
* 总是处于活跃状态的 Observer包装类
*/
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
3. LifecycleBoundObserver
顾名思义,生命周期约束ObserverWrapper。方法observe( LifecycleOwner , observer)中指定注册的ObserverWrapper。
/**
* 生命周期约束Observer
*/
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
/**
* 确定Observer在处于STARDED和RESUMED状态时,处于活动状态
*/
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
/**
* 相较父类的方法多了一层判断,当mOwner处于DESTROYED状态时自动将Observer从LiveData的观察者列表mObservers中移除
*/
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
/**
* 移除在mOwner观察列表中的LifecycleBoundObserver
*/
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
总结
-
LiveData中的观察者注册和数据刷新处理必须运行在MainThread中。因为其原理相当于在MainThread新建了一个LiveData变量,所有的LiveData相关的操作实际都是运行在主线程中的。
-
当LiveData调用onInactive时,LiveData中没有actively的观察者可以释放任何繁重的资源。
相关链接:
博客书写不易,您的点赞收藏是我前进的动力,千万别忘记点赞、 收藏 ^ _ ^ !