我想从源码知道些什么内容
- 如何实现其它对象观察组件(Activity/Fragment)的生命周期状态?
- 在其它对象中观察到组件(Activity/Fragment)的生命周期我们可以做哪些事情?
Tip:
源码:Android API 29
LifeCycle 的使用
// 定义生命周期观察者
class MyLocationListener implements LifecycleObserver {
public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// connect to system location service
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// disconnect if connected
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
// update UI
});
// 添加观察者
getLifecycle().addObserver(myLocationListener)
}
}
参考示例:
如果是使用ViewModel+LiveData
开发则可不必单独引入LifeCycle
库
下面让我们进入源码中一探究竟吧
(1) 其它对象如何获取组件(Activity/Fragment)的生命周期状态?
从使用流程中我们发现,要想其它对象能观察到组件(Activity/Fragment)的生命周期状态,
我们需要让该对象实现LifecycleObserver
接口,
并通过向其方法添加注解来监控组件的生命周期状态,
最后在组件(Activity/Fragment)的 onCreate() 方法中使用组件(Activity/Fragment)的 Lifecycle.addObserver(MyObserver())
对其进行初始化。
那么组件(Activity/Fragment)中是如何实现生命周期的观察呢?
通过LifeCycle
库的介绍,要想实现自定义类具有声明周期感知,需要实现了LifecycleOwner
并重写了getLifecycle
方法
这里以 源码:
Android API 29
进行分析。
我们知道Android API 26
以后默认给AppCompatActivity
添加了生命周期感知。因此我们可以进入到父类中查看LifeCylce
如何实现的。
在源码中我们可以看到ComponentActivity.java
实现了LifecycleOwner
并重写了getLifecycle
方法,该方法返回mLifecycleRegistry
对象
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
而 mLifecycleRegistry
是 LifecycleRegistry
的实例
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
...
}
我们进入到LifecycleRegistry
内部发现它其实是继承Lifecycle
public class LifecycleRegistry extends Lifecycle {
...
}
所以 LifecycleRegistry
就是生命周期检测的核心实现类了。
那么它是如何接收到组件的生命周期并处理的呢?
既然要接收组件的生命周期,那在组件的相关生命周期方法中肯定有相关的方法通过LifecycleRegistry
对象传递调用后传递给LifecycleRegistry
内部处理
在AppCompatActivity.java 的父类 FragmentActivity.java
的各个生命周期方法中,我们找到了LifecycleRegistry
的对象,以及该对象调用的方法handleLifecycleEvent
示例如下:
@Override
protected void onDestroy() {
super.onDestroy();
mFragments.dispatchDestroy();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
handleLifecycleEvent
的实现如下:
/**
* Sets the current state and notifies the observers.
* @param event The event that was received
*/
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
从注释我们可以知道该方法的作用是设置当前的state
并通过该state
的观察者去完成相关的任务
在FragmentActivity.java 的父类 ComponentActivity.java
的构造函数中,我们可以找到对应state
的观察者
示例如下:
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
这里的addObserver
顾名思义就是添加观察者,而这个观察者需要实现实现LifecycleObserver
接口,
如下:
public interface LifecycleEventObserver extends LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
那么这里的关键点就是addObserver
是如何将生命周期传递给实现了LifecycleObserver
的对象呢?
进入到addObserver
源码
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// observer 就是传递进来的观察者,生成有状态的 Observer
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 从 mObserverMap 集合中获取
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
// 如果不为null,代表添加的 observer 已经添加过一次了直接返回
if (previous != null) {
return;
}
// 获取具有生命周期感知的类,为 null 则直接返回
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
// 是否重入
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//需要分发到的状态,根据activity的当前状态与mParentStates的状态对比,选出最小的那个
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// 循环分发更大的state。
// 例如在一个观察者中又添加一个观察者,默认情况下观察者都能观察到组件的所有生命周期。
// 但是如果在添加第二个观察者时增加了 state 的判断,例如当 state == Lifecycle.Event.ON_DESTROY
// 那么第二个观察者就只会监听到 Lifecycle.Event.ON_DESTROY 事件。
while ((statefulObserver.mState.compareTo(targetState) < 0 && mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
// 分发事件
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
// 不是重入状态,同步观察者 observer 的生命周期状态
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
// 分发事件方法
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
// 回调观察者定义的方法
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
小结:
其它对象如何获取组件(Activity/Fragment)的生命周期状态?
- 创建对象并实现
LifecycleObserver
接口:这里主要作用是在生命周期改变时将对应的State
发送给观察者,也就是该对象。 - 组件实现
LifecycleOwner
接口:作用是获取LifeCycle
,而LifeCycle
是抽象类,主要使用的还是它的实现类LifecycleRegistry
- 在组件
(Activity/Fragment)
中addObserver
并可在对应的State
处理对应逻辑:这里addObserver
就是将观察者放到FastSafeIterableMap
中,并找到当前最小的State
,根据最小的State
去循环发送给观察者。这里之所以根据最小的State
去传递,主要是防止State
重入问题。具体可看上面源码中的注释。
(2) 在其它对象中观察到组件(Activity/Fragment)的生命周期我们可以做哪些事情?
- 尽可能保持组件(Activity/Fragment)精简。它们不应试图获取自己的数据,而应使用 ViewModel 执行此操作,并观察 LiveData 对象以将更改体现到视图中。
- 停止和开始视频缓冲。使用生命周期感知型组件可尽快开始视频缓冲,但会推迟播放,直到应用完全启动。此外,应用销毁后,您还可以使用生命周期感知型组件终止缓冲。
- 开始和停止网络连接。借助生命周期感知型组件,可在应用位于前台时启用网络数据的实时更新(流式传输),并在应用进入后台时自动暂停。
- 暂停和恢复动画可绘制资源。借助生命周期感知型组件,可在应用位于后台时暂停动画可绘制资源,并在应用位于前台后恢复可绘制资源。
如需要更细粒度的管理数据的生命周期,可借助生命周期感知型组件 LiveData,应用可以在用户使用位置发生变化时自动更新界面。
后面也会分析LiveData
的源码
Tips:
最近阅读一些库的源码总会发现使用隐藏的Fragment去管理生命周期
,比如:
- RxBus 的实现。使用时主要关心发送和接收,注册和注销都在隐藏的
Fragment
中自动处理了。 - RxPermission 权限的申请和回调都在隐藏的
Fragment
中自动处理了。 - Glide 生命周期监听也是采用这种方式。
而以上实现库的实现原理有两种方式:
- 内部的
Fragment
监听FragmentLifecycleCallbacks
,这是Android4.0
提供的机制 - 使用高版本(目前api 29 中可以使用,其它版本暂未查看)的
Fragment
再通过实现LifecycleObserver
接口去监听到生命周期的变化。
更多的开源库为了兼容低版本还是使用第一种方式。
总结
LifeCycle
的主要作用:
-
尽可能保持组件(Activity/Fragment)精简。
因为其它对象可以通过实现LifeCycleObserver
来监听到生命周期的变化,所有之前在组件中的业务处理可以分离给其它类操作。 -
大部分开源库的实现,如需要对生命周期的管理,基本上都会使用隐藏的
Fragment
实现。 -
LifeCycle
生命周期监听是通过观察者模式来实现。
内部的实现是在组件添加观察者并中传递上下文给LifeCycle
,
而具体是由LifecycleRegistry
实现类去根据最小的 state
以及FastSafeIterableMap
中是否存在,存在且当前的Enum state
小于最小的Enum state
则去通知观察者。
这里Enum
的比较,主要是比较ordinal()
值的大小
当此Enum
对象=
给定的Enum
对象时,它将返回0
当此Enum
对象>
给定的Enum
对象时,它将返回正值
当此Enum
对象<
给定的Enum
对象时,它将返回负值