JetPack | Lifecycle 如何做到感知生命周期
LifeCycle的作用是什么:生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您编写出更有条理且往往更精简的代码,此类代码更易于维护(摘自Android官网的解释)。 Lifecycle 最早是在 support 26.1.0 时被引入的,目前已经成为源码的一部分,而几乎无需使用者在 Gradle 额外地配置依赖。 Lifecycle的出现,可以帮助我们感知生命周期。
关于LifeCycle的使用这里不在复述直接看官方文档,本篇文章旨在理解Lifecycle的本质以及优秀代码的设计思想。
Lifecycle出现的背景原因
在LifeCycle没有出现之前,如果外部类要先监听Activity/Fragment的生命周期,需要定义个接口来监听Activity的生命周期方法(onCreate onStart onResume)等。避免内存泄漏等问题。 如下代码:随着Activity的功能越来越复杂,Listener处理的事情就会越来越多,最终导致代码难以维护。
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// connect to system location service
}
void stop() {
// disconnect from system location service
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// update UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
// manage other components that need to respond
// to the activity lifecycle
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
// manage other components that need to respond
// to the activity lifecycle
}
}
那么Lifecycle是如何实现组件的隔离呢?
Lifecycle 实现隔离
在Android的官方文档中看到有两个关键的接口LifecycleOwner
表示该类具有Lifecycle 和LifecycleObserver
** 监听生命周期事件** 以及 [LifecycleRegistry](https://developer.android.com/reference/androidx/lifecycle/LifecycleRegistry?hl=zh-cn)
**将生命周期事件转发 ** 下面我们来自定义LifecycleOwner来实现Lifecycle的完整流转。
open class LActivity:Activity(),LifecycleOwner {
/**
* 负责转发生命周期事件
*/
private var mFragmentLifecycleRegistry = LifecycleRegistry(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
}
override fun onStart() {
super.onStart()
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
override fun onResume() {
super.onResume()
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
}
override fun onStop() {
super.onStop()
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
}
override fun onDestroy() {
super.onDestroy()
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
override fun getLifecycle(): Lifecycle {
return mFragmentLifecycleRegistry
}
}
LifecycleEventObserver
监听生命周期:
class LifecycleActivity : LActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
//感知生命周期
lifecycle.addObserver(MyLifecycleObserver())
}
}
/**
* 监听生命周期
*/
class MyLifecycleObserver:LifecycleEventObserver{
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
Log.e("MyLifecycleObserver", "onStateChanged: ${source.lifecycle.currentState} event:${event}" )
}
}
运行结果如下:Lifecycle的事件以及状态的对应关系
image.png
在Android的官方文档 给出的事件和状态的关系,如下图和我们上述的是一致的。 事件是监听生命周期的而状态是判断页面是否处于激活状态。
image.pngON_CREATE 和 ON_STOP 对应着CREATED。ON_START和ON_PAUSE对应着STARTED。这样的状态对应是因为ON_PAUSE有重走onStart的潜力,而ON_STOP有重走onCreate的潜力
那么Lifecycle为什么要设计事件和状态呢?
Lifecycle事件和状态的对应关系
- event:实现了
LifecycleObserver
的第三方组件,能够在onCreate
到onDestroy
等 event 方法内完成对生命周期的监听,event 是针对 第三方组件内部作为观察者,来观察 页面对组件的推送。 - state :的存在,主要是 为了方便使用者判断 页面是否处于激活状态,以便实现生命周期安全的通知,state 是针对 页面作为观察者,来观察 来自第三方组件内部对页面的推送,那么此时通过 state 的判断,我们可确保在页面处于非激活状态时不收到 基于 LifeCycle 的组件(比如 LiveData)的推送。
LiveData是根据State来判断生命周期是否处于活跃状态的,如下代码:
lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
只有 onResume 和 onPause 是介于 STARTED、RESUMED 状态之间,也即 只有这两个生命周期节点 100% 确定能收到 LiveData 的推送(FragmentActivity 额外支持 onStart 期间的接收)。
LifecycleRegistry 核心类
image.pngLifecycleRegistry 的设计如何去分发事件。其实看到源码可以和LiveData的分发消息差不多。
如下代码:通过handleLifecycleEvent发送生命周期事件
// 分发生命周期事件
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
private void moveToState(State next) {
......
sync();
......
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
....
while (!isSynced()) {
mNewEventOccurred = false;
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Map.Entry<LifecycleObserver, ObserverWithState> newest =
mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
sync()
方法分别调用了forwardPass
和backwardPass
进行分发生命周期事件。 监听生命周期事件及状态: mObserverMap
存储监听ObserverWithState
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
addObserver
添加监听事件,将obsever
包装成ObserverWithState
(这一段代码和LiveData中的observer
类似)
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//observer 包装ObserverWithState
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//mObserverMap 存储statefulObserver
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//.......
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//重复addObserver 会返回之前的状态
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + statefulObserver.mState);
}
//发送生命周期事件
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
ObserverWithState
包装类通过dispatchEvent
,在通过mLifecycleObserver.onStateChanged
分发事件
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 = event.getTargetState();
//判断当前的状态
mState = min(mState, newState);
//发送事件及状态
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}