Lifecycle 概述
Google官方向我们推出了 Android Architecture Components,其中谈到Android组件处理生命周期的问题,向我们介绍了 Handling Lifecycles。同时,如何利用 android.arch.lifecycle 包提供的类来控制数据、监听器等的 lifecycle。同时,LiveData 与 ViewModel 的 lifecycle 也依赖于Lifecycle框架。不久前, Android Architecture Components 正式Release,Lifecycle也正式植入进了SupportActivity(AppCompatActivity的基类)和Fragment中。
简介
Lifecycle 是一个存储某组件(如 acitivity 或 fragment)生命周期状态的信息的类,并且它还允许其他对象观察这个状态。从而在外部实现监听,能够使我们及时根据组件的生命周期变化做出相应动作,比如释放资源等,从而避免内存泄露和程序崩溃。
在开发应用时,我们可能会基于一系列的生命周期实现某种功能。之前一种常见的模式是在 acitivity 和 fragment 的生命周期方法中实现相关组件(dependent components)的行为,然而这种模式会导致混乱的代码和激增的错误。见下面的demo。
class MyPresenter{
public MyPresenter() {
}
void create() {
//do something
}
void start() {
//do something
}
void destroy() {
//do something
}
}
class MyActivity extends AppCompatActivity {
private MyPresenter presenter;
@Override
public void onCreate(...) {
presenter= new MyPresenter ();
presenter.create();
}
@Override
public void onStart() {
super.onStart();
presenter.start();
}
@Override
public void onDestroy() {
super.onDestroy();
presenter.destory();
}
}
尽管这个例子看起来没什么问题,但在一个真实的应用中,您会发现最后有太多更新 UI 和其他组件相应当前生命周期状态的调用了。为了管理多个组件,您不得不向 onStart() 和 onStop() 等生命周期方法中添加大量的代码,这样就很难维护。
更糟的是,没人能保证这些组件会在 activity 或 fragment 停止前开始,尤其是在需要执行耗时较长的操作时,例如 onStart() 中的某些配置检查。这就会出现竞争情况(race condition),导致 onStop() 方法提前于 onStart() 结束,从而使这些组件存活得过久。
class MyActivity extends AppCompatActivity {
private MyPresenter presenter;
@Override
public void onCreate(...) {
presenter= new MyPresenter ();
presenter.create();
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
// what if this callback is invoked AFTER activity is stopped?
if (result) {
presenter.start();
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
presenter.destory();
}
}
为了复用,也为了不让应用组件变得很臃肿,实现该功能时会选择与生命周期组件解藕,独立成一种组件。这样能够很方便地在应用组件中使用,比如:Activity、Fragment 或 Service。
Android 官方把它叫做 lifecycle-aware 组件,这类组件会根据其他组件(例如 activity 和 fragment)的生命周期的状态改变而做出反应,从而帮助您编写更有条理、轻量且易于维护的代码。
通过使用能感知生命周期的组件,您就能将相关组件的代码从生命周期方法中移出到这些组件自身中去。
为了方便开发者创建 lifecycle-aware 组件,android.arch.lifecycle 包提供了让您构建能感知生命周期的组件的类和接口。
注意:欲将
android.arch.lifecycle导入到您的 Android 项目中,请参阅为您的项目添加 Android 架构组件。
Android 框架中定义的大部分应用组件都附有相应的生命周期,而生命周期则是由操作系统、或是您的进程中运行的框架代码来管理。它们对于 Android 的正常工作来说是至关重要的,因此您的应用必须尊重其规律,否则就可能导致内存泄漏、甚至应用崩溃。
Demo
-
Prestener继承LifecycleObserver接口
public interface IPresenter implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) void onCreate(@NotNull LifecycleOwner owner); @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) void onDestroy(@NotNull LifecycleOwner owner); @OnLifecycleEvent(Lifecycle.Event.ON_ANY) void onLifecycleChanged(@NotNull LifecycleOwner owner, @NotNull Lifecycle.Event event); } public class BasePresenter implements IPresenter { private static final String TAG = "BasePresenter"; @Override public void onLifecycleChanged(@NotNull LifecycleOwner owner, @NotNull Lifecycle.Event event) { } @Override public void onCreate(@NotNull LifecycleOwner owner) { Log.d(TAG, "BasePresenter.onCreate" + this.getClass().toString()); } @Override public void onDestroy(@NotNull LifecycleOwner owner) { Log.d(TAG, "BasePresenter.onDestroy" + this.getClass().toString()); } } public class MainPresenter extends BasePresenter { //... }这里我直接将我想要观察到
Presenter的生命周期事件都列了出来,然后封装到BasePresenter中,这样每一个BasePresenter的子类都能感知到Activity容器对应的生命周期事件,并在子类重写的方法中,对应相应行为。 -
在Activity/Fragment中添加Observer
public class MainActivity extends AppCompatActivity { private IPresenter mObserver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("tag", "onCreate" + this.getClass().toString()); setContentView(R.layout.activity_main); mObserver = new MainPresenter(this); getLifecycle().addObserver(mObserver);//添加LifecycleObserver } @Override protected void onDestroy() { Log.d("tag", "onDestroy" + this.getClass().toString()); super.onDestroy(); } }如此,每当Activity发生了对应生命周期改变,Presenter就会执行对应事件注解的方法,只要通过注解进行声明,就能够使LifecycleObserver观察到对应的生命周期事件。
源码分析
借鉴Android 架构组件(一)——Lifecycle里的一张图进行简单的概括:
我们先将重要的这些类挑选出来:
- LifecycleObserver接口(生命周期观察者):实现该接口的类,通过注解的方式,可以通过被
LifecycleOwner类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。 - LifecycleOwner接口(生命周期所有者):实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。
- Lifecycle(生命周期):和LifecycleOwner不同的是,LifecycleOwner本身持有Lifecycle对象,LifecycleOwner通过其getLifecycle()获取内部Lifecycle对象。
- State(当前生命周期所处状态):如图所示。
- Event(当前生命周期改变对应的事件):如图所示,当Lifecycle发生改变,如进入onCreate,会自动发出ON_CREATE事件。
简单来说,LifecycleOwner 用于提供 Lifecycle,LifecycleObserver 监听 Lifecycle 的状态变化,Lifecycle 则是 Activity 或 Fragment 生命周期状态的抽象。
了解了这些类和接口的职责,接下来原理分析就简单很多了,我们来看下实际Fragment/Activity等类和上述类或接口的联系:
生命周期所有者(LifecycleOwner)
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
LifecycleOwner 是仅包含了一个方法(getLifecycle())的接口,通过@NonNull强制我们返回Lifecycle对象。
LifecycleOwner用以表示某个类拥有 Lifecycle。这唯一的 getLifecycle() 方法必须由那个类实现。另一方面,如果您试图管理的是整个应用进程的生命周期,请参阅 ProcessLifecycleOwner。
该接口将 Lifecycle 的所有权从各自的类(如 Fragment 和 AppCompatActivity)中抽象出来,并允许用户编写与其协作的组件。任何定制的应用类都可以实现该接口。
实现了 LifecycleObserver 的接口的组件能够和实现了 LifecycleOwner 的组件无缝衔接,因为后者可以提供一个被前者注册以观察的生命周期。
如果一个库提供了需要和 Android 生命周期协调的类,我们推荐您使用能感知生命周期的组件。您的库的用户可以轻易地整合这些组件,而毋须手动地管理生命周期。
26.1.0 及更新版本的支持库里的 Fragments 和 Activity 已经实现了
LifecycleOwner接口。
androidx.fragment.app.Fragment
我们先看看androidx中的fragment中的实现
public class Fragment implements ..., LifecycleOwner {
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
void performCreate(Bundle savedInstanceState) {
//1.先执行生命周期方法
onCreate(savedInstanceState);
//...省略代码
//2.生命周期事件分发
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart() {
onStart();
//...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
void performResume() {
onResume();
//...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
void performPause() {
//3.注意,调用顺序变了
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
//...
onPause();
}
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
//...
onStop();
}
void performDestroy() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
//...
onDestroy();
}
}
随着Fragment不同走到不同的生命周期,除了暴露给我们的生命周期方法onCreate/onStart/..../onDestroy等,同时,Fragment内部的Lifecycle对象(就是mLifecycleRegistry)还将生命周期对应的事件作为参数传给了 LifecycleRegistry#handleLifecycleEvent() 方法。这个方法分析见后文。
同时,你会发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法。
参照Android 架构组件(一)——Lifecycle文中的时序图:
androidx.core.app.ComponentActivity
我们再看看androidx中的ComponentActivity中的实现
public class ComponentActivity extends Activity implements LifecycleOwner,ViewModelStoreOwner, SavedStateRegistryOwner, OnBackPressedDispatcherOwner{
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
ReportFragment.injectIfNeededIn(this);
//...
}
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
上面就是lifecycle相关的核心代码了,可以看到它并没有像Fragment一样在各个生命周期函数中调用mLifecycleRegistry.handleLifecycleEvent来发出事件,那么它是如何让做LifecycleObserver感受到到ComponentActivity的生命周期变化的呢?
其实关键点就在于onCreate()方法中的ReportFragment.injectIfNeededIn(this)。
我们看下ReportFragment
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib, so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
static ReportFragment get(Activity activity) {
return (ReportFragment) activity.getFragmentManager().findFragmentByTag(
REPORT_FRAGMENT_TAG);
}
private ActivityInitializationListener mProcessListener;
private void dispatchCreate(ActivityInitializationListener listener) {
if (listener != null) {
listener.onCreate();
}
}
private void dispatchStart(ActivityInitializationListener listener) {
if (listener != null) {
listener.onStart();
}
}
private void dispatchResume(ActivityInitializationListener listener) {
if (listener != null) {
listener.onResume();
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
// just want to be sure that we won't leak reference to an activity
mProcessListener = null;
}
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
void setProcessListener(ActivityInitializationListener processListener) {
mProcessListener = processListener;
}
interface ActivityInitializationListener {
void onCreate();
void onStart();
void onResume();
}
}
ReportFragment代码很简单,重写生命周期函数,并调用dispatch(Lifecycle.Event event)方法,来分发生命周期事件,这就是“生命周期感知能力”的来源。向 Activity 注册一个无 UI 的 Fragment 也叫 Headless Fragment 用于将各种 Activity 回调分离出来是个常用的做法,比如权限请求库 RxPermission ,以及 airbnb 开源的用于URL跳转的 DeepLinkDispatch(前者是使用空的 Fragment,后者使用的是空的 Activity)
Activity 的生命周期变化是如何传递到 LifecycleObserver 有了清晰的图表:
最终也是调用((LifecycleRegistry) lifecycle).handleLifecycleEvent(event)方法,和上面一样,先不分析,下文会有分析的。
android.app.Activity
这是普通Activity,如果想让这个Activity定制成 LifecycleOwner,您可以使用 LifecycleRegistry 类
网上很多文章都是按下面的方法做的
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry lifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
lifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
}
思路就是实例化一个LifecycleRegistry,然后重写Activity生命周期函数,再通过lifecycleRegistry.markState来分发事件。
虽然通过重写 Activity 生命周期,并通过在各方法中仅添加一行lifecycleRegistry.markState()代码就能实现生命周期的感知。但是,作为推动社会发展的“懒人” -- 程序员,自然想通过更简单的方式来解放右手。办法总比困难多。
从前面我们知道,通过继承 AppCompactActivity 这种实现方式中核心就是向 Activity 中注入一个空的 Fragment--ReportFragment。我们能不能也通过这种方式,动态的向 Activity 中注入这个 ReportFragment 呢?
答案是行的,而且google已经帮我们实现了。
Google 为我们提供了一个extensions库,我们需要单独引入:
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
引入该库之后,我们的使用方式,就跟继承自 AppCompactActivity 基本相同,唯一的不同点就是我们需要自己实现 LifecycleOwner ,提供一个LifecycleRegistry(不要担心,一行代码,直接用现成的就好)
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry lifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
// 不再需要手动调用 markstate方法了
//lifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
// 不再需要手动调用 markstate方法了
// lifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
}
是不是很神奇,这是如何实现的呢,我们顺着代码反推下:
我们Command/Ctrl+鼠标左键,点击ReportFragment,会发现使用到它的有两个类:LifecycleDispatcher.java 和 ProcessLifecycleOwner.java这两个类,而这二者,就是extensions这个库下的类。
那我们就先追踪ReportFragment.injectIfNeededIn(activity)在LifecycleDispatcher.java类中的调用:
class LifecycleDispatcher {
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.injectIfNeededIn(activity);
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
}
private LifecycleDispatcher() {
}
}
ReportFragment.injectIfNeededIn(activity) 这行代码是在 LifecycleDispatcher 的静态内部类DispatcherActivityCallback的 onActivityCreated(…) 方法中调用的。而DispatcherActivityCallback又继承自EmptyActivityLifecycleCallbacks,EmptyActivityLifecycleCallbacks是啥?它其实就是Application.ActivityLifecycleCallbacks接口的空实现类。
class EmptyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
继续回到上面的 LifecycleDispatcher 的源码查看,发现静态内部类 DispatcherActivityCallback 的实例化是在LifecycleDispatcher类的static方法init()中,在该方法中进行监听器的注册:
class LifecycleDispatcher {
private static AtomicBoolean sInitialized = new AtomicBoolean(false);
static void init(Context context) {
if (sInitialized.getAndSet(true)) {
return;
}
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
//...
}
这里面,就真正的看到了通过Application的registerActivityLifecycleCallbacks来注册监听器。
继续追踪LifecycleDispatcher#init(...)方法在哪调用的,就进入了ProcessLifecycleOwnerInitializer类的onCreate()方法:
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
//...
}
ProcessLifecycleOwnerInitializer是继承自ContentProvider,在其 onCreate() 方法中,进行了LifecycleDispatcher 的初始化,并且也进行了ProcessLifecycleOwner 的初始化。关于ProcessLifecycleOwner ,后文有介绍。
通过看源码,发现它对 ContentProvider 的各种方法都进行了空实现。其实,这里就是利用了 ContentProvider 的隐式加载。它的 onCreate() 方法执行时机是在Application#onCreate()方法之前。这样它就能通过 Application 来监听 Activity 的创建,并判断是否已经添加过了一个空UI的 ReportFragment。若没有,就进行添加。这种设计真的是太妙了。
这里 ContentProvider 之于 Application 的作用就类似于 Headless Fragment 之于 Activity 一样,目的都是避免继承系统组件。关于 ContentProvider 的生命周期可以看 android - ContentProvider destruction/lifecycle - Stack Overflow,
我们知道,四大组件都是要在 AndroidManifest.xml 文件中进行生命的。那这个 ContentProvider 类型的 ProcessLifecycleOwnerInitializer 又是在什么时候声明的呢?
我们找到extensions库,通过如下方式查看它的下载位置:
Android Studio 切换到 Project 模式,在External Libraries中找到这个类所在的位置,右键下图箭头所指classes.jar 选择在本地显示。
在这个jar的上级目录下 有个AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidx.lifecycle.process" >
<uses-sdk android:minSdkVersion="14" />
<application>
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="${applicationId}.lifecycle-process"
android:exported="false"
android:multiprocess="true" />
</application>
</manifest>
在这里我们果真找到了声明。
这里的AndroidManifest.xml最终会合并入我们app module 的AndroidManifest.xml文件中。
反推结束,我们再反过来梳理一遍:
-
在清单文件注册的
ProcessLifecycleOwnerInitializer,这个provider在onCreate中调用了LifecycleDispatcher.init(getContext()) -
LifecycleDispatcher.init(getContext())方法调用了((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(new DispatcherActivityCallback()); -
DispatcherActivityCallback中的onActivityCreated中调用了ReportFragment.injectIfNeededIn; -
ReportFragment.injectIfNeededIn方法把ReportFragment的各个生命周期中调用了加入到我们activity中 -
在
ReportFragment的各个生命周期中调用了它的dispatch()方法。 -
dispatch()调用了
LifecycleRegister的handleLifecycleEvent()。
三个情况都分析完了,最后大家都是调用LifecycleRegister的handleLifecycleEvent()
所以我们接下来分析LifecycleRegistry类
而LifecycleRegistry继承自Lifecycle类
我们可以先看下Lifecycle
生命周期 (Lifecycle )
public abstract class Lifecycle {
/**
* Adds a LifecycleObserver that will be notified when the LifecycleOwner changes
* state.
* <p>
* The given observer will be brought to the current state of the LifecycleOwner.
* For example, if the LifecycleOwner is in {@link State#STARTED} state, the given observer
* will receive {@link Event#ON_CREATE}, {@link Event#ON_START} events.
*
* @param observer The observer to notify.
*/
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
/**
* Removes the given observer from the observers list.
* <p>
* If this method is called while a state change is being dispatched,
* <ul>
* <li>If the given observer has not yet received that event, it will not receive it.
* <li>If the given observer has more than 1 method that observes the currently dispatched
* event and at least one of them received the event, all of them will receive the event and
* the removal will happen afterwards.
* </ul>
*
* @param observer The observer to be removed.
*/
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
/**
* Returns the current state of the Lifecycle.
*
* @return The current state of the Lifecycle.
*/
@MainThread
@NonNull
public abstract State getCurrentState();
// Event 对应 activity 的各个生命周期
//ON_ANY事件可以代表前面任意一种。
//举个例子,当Activity的onCreate()生命周期方法被调用时会产生ON_CREATE事件,观察者可以监听该事件以便处理Activity此时的生命周期。
@SuppressWarnings("WeakerAccess")
public enum Event {
ON_CREATE, //用于匹配生命周期所有者的onCreate事件.
ON_START, //用于匹配生命周期所有者的onStart事件.
ON_RESUME, //用于匹配生命周期所有者的onResume事件.
ON_PAUSE, //用于匹配生命周期所有者的onCreate事件.
ON_STOP, //用于匹配生命周期所有者的onStop事件.
ON_DESTROY, //用于匹配生命周期所有者的onDestroy事件.
ON_ANY //用于匹配生命周期所有者的所有事件.
}
/**
* Lifecycle states. You can consider the states as the nodes in a graph and
* {@link Event}s as the edges between these nodes.
*/
@SuppressWarnings("WeakerAccess")
public enum State {
/**
* Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch
* any more events. For instance, for an {@link android.app.Activity}, this state is reached
* <b>right before</b> Activity's {@link android.app.Activity#onDestroy() onDestroy} call.
*/
DESTROYED,
/**
* Initialized state for a LifecycleOwner. For an {@link android.app.Activity}, this is
* the state when it is constructed but has not received
* {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet.
*/
INITIALIZED,
/**
* Created state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;
* <li><b>right before</b> {@link android.app.Activity#onStop() onStop} call.
* </ul>
*/
CREATED,
/**
* Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {@link android.app.Activity#onStart() onStart} call;
* <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call.
* </ul>
*/
STARTED,
/**
* Resumed state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached after {@link android.app.Activity#onResume() onResume} is called.
*/
RESUMED;
/**
* Compares if this State is greater or equal to the given {@code state}.
*
* @param state State to compare with
* @return true if this State is greater or equal to the given {@code state}
*/
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
Lifecycle 类表示Android应用组件的生命周期,是被观察者。这是一个抽象类,它的实现是 LifecycleRegistry 类。
Lifecycle 对象有3个方法:
- 添加观察者:
void addObserver(LifecycleObserver observer)。 - 删除观察者:
void removeObserver(LifecycleObserver observer)。- - 获取当前状态:
State getCurrentState()。
Lifecycle的2个关键方法中参数都是LifecycleObserver
所以在分析 LifecycleRegistry之前我们先看下LifecycleObserver
生命周期观察者 (LifecycleObserver)
LifecycleObserver 基本介绍
标记接口 LifecycleObserver 表示生命周期观察者,是 lifecycle-aware 组件。
public interface LifecycleObserver {
}
这个接口用来声明它的实现类是生命周期观察者 ,我们要在这个类里接收到LifecycleOwner的生命周期变化事件,然后做自身逻辑。
但当我们看到LifecycleObserver这个接口时,第一感觉是比较奇怪:这个接口竟然是空的。那我们如何去接受生命周期变化的事件呢?(通常正常的是回调接口)
其实开头就介绍过用法了,google的做法是配合注解 OnLifecycleEvent 使用,LifecycleObserver 只是起一个声明和约束作用。其内部继承数如下图:
看到这么多类似的接口,我猜或许这是因为生命周期钩子比较多,如果全都放在接口里,那么实现者需要添加很多空实现方法,可阅读性降低。
比如FullLifecycleObserver
interface FullLifecycleObserver extends LifecycleObserver {
void onCreate(LifecycleOwner owner);
void onStart(LifecycleOwner owner);
void onResume(LifecycleOwner owner);
void onPause(LifecycleOwner owner);
void onStop(LifecycleOwner owner);
void onDestroy(LifecycleOwner owner);
}
这个接口就将所有的生命周期函数声明了,如果我们实现这个接口,就得重写所有接口,然而我们不一定要用这么多接口。(其实你想用也用不了,这个接口不是public,我们不能实现)
我们知道用注解的话大多数是反射解析的,这就涉及到性能问题,当然使用apt可以在编译期解决这个问题。这点后文会详细分析。
如果我们不想用注解,又不想一下子实现所有的方法,可以吗? 答案是肯定的。java8的接口default方法。而且google也鼓励我们用这种方式,那就是DefaultLifecycleObserver
DefaultLifecycleObserver
注意:在androidx.lifecycle.Lifecycle类的顶部注释里有一段
/**
* If you use <b>Java 8 Language</b>, then observe events with {@link DefaultLifecycleObserver}.
* To include it you should add {@code "androidx.lifecycle:common-java8:<version>"} to your
* build.gradle file.
* <pre>
* class TestObserver implements DefaultLifecycleObserver {
* {@literal @}Override
* public void onCreate(LifecycleOwner owner) {
* // your code
* }
* }
* </pre>
* If you use <b>Java 7 Language</b>, Lifecycle events are observed using annotations.
* Once Java 8 Language becomes mainstream on Android, annotations will be deprecated, so between
* {@link DefaultLifecycleObserver} and annotations,
* you must always prefer {@code DefaultLifecycleObserver}.
* <pre>
* class TestObserver implements LifecycleObserver {
* {@literal @}OnLifecycleEvent(ON_STOP)
* void onStopped() {}
* }
* </pre>
* <p>
* Observer methods can receive zero or one argument.
* If used, the first argument must be of type {@link LifecycleOwner}.
* Methods annotated with {@link Event#ON_ANY} can receive the second argument, which must be
* of type {@link Event}.
* <pre>
* class TestObserver implements LifecycleObserver {
* {@literal @}OnLifecycleEvent(ON_CREATE)
* void onCreated(LifecycleOwner source) {}
* {@literal @}OnLifecycleEvent(ON_ANY)
* void onAny(LifecycleOwner source, Event event) {}
* }
* </pre>
* These additional parameters are provided to allow you to conveniently observe multiple providers
* and events without tracking them manually.
*/
public abstract class Lifecycle {
}
意思就是一旦Java 8成为Android的主流,注解将被弃用,所以介于DefaultLifecycleObserver和注解两者之间,更推荐使用 DefaultLifecycleObserver 。
使用方式如下
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
这个库里其实就一个 DefaultLifecycleObserver.java 接口类。之后我们需要 LifecycleObserver 的时候,一般实现 DefaultLifecycleObserver 接口即可(不用再去直接实现 LifecycleObserver 接口),使用方式变成了下面这样:
class NormalActivity : Activity(), LifecycleOwner {
private var lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_normal)
lifecycle.addObserver(object : DefaultLifecycleObserver {
//下面的方法视自身情况选择实现
override fun onCreate(owner: LifecycleOwner) {
}
override fun onStart(owner: LifecycleOwner) {
}
override fun onResume(owner: LifecycleOwner) {
}
override fun onPause(owner: LifecycleOwner) {
}
override fun onStop(owner: LifecycleOwner) {
}
override fun onDestroy(owner: LifecycleOwner) {
}
})
}
}
可以看到,这里我们直接在覆写我们需要的生命周期对应回调方法中写入我们的逻辑代码即可。更加简洁。
LifecycleObserver 之间的转换
我们在使用 LifecycleObserver时,框架内部会将其转换为GenericLifecycleObserver 或其子类。 其转换行为在类 androidx.lifecycle.Lifecycling#getCallback 中。至于这个方法何时触发,我们后续会分析。
现在先看下这个转换过程
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
// 如果是 FullLifecycleObserver, 转换为 FullLifecycleObserverAdapter
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}
// 如果是 GenericLifecycleObserver, 不转换
if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}
final Class<?> klass = object.getClass();
// 获取转换type, GENERATED_CALLBACK 为使用代码生成,REFLECTIVE_CALLBACK 为使用反射调用
int type = getObserverConstructorType(klass);
if (type == GENERATED_CALLBACK) {
// 采用代码生成
List<Constructor<? extends GeneratedAdapter>> constructors =
sClassToAdapters.get(klass);
// 一个构造函数
if (constructors.size() == 1) {
GeneratedAdapter generatedAdapter = createGeneratedAdapter(
constructors.get(0), object);
return new SingleGeneratedAdapterObserver(generatedAdapter);
}
// 多个构造函数
GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
for (int i = 0; i < constructors.size(); i++) {
adapters[i] = createGeneratedAdapter(constructors.get(i), object);
}
return new CompositeGeneratedAdaptersObserver(adapters);
}
// 默认采用反射调用
return new ReflectiveGenericLifecycleObserver(object);
}
这个方法的本质,其实就是根据传进来的一个LifecycleObserver 对象,构造出来一个 GenericLifecycleObserver 对象(目前有四个子类:FullLifecycleObserverAdapter、SingleGeneratedAdapterObserver、CompositeGeneratedAdaptersObserver、ReflectiveGenericLifecycleObserver),而最终构造出来的对象,就包含了我们创建的 LifecycleObserver 的所有信息,包括各种回调方法等。
当我们通过注解的方式来自定义LifecycleObserver 的时候,按照传统方式,必定要通过反射来对注解进行解析,这样就会对性能造成影响。那么如何优化呢?
-
通过缓存,来避免每次都通过反射获取构造器。
-
通过注解处理器,在编译时对那些被
@OnLifecycleEvent注解标注的普通方法,进行预处理,生成以“类名_LifecycleAdapter”命名的类,将各种回调方法直接进行逻辑转换,避免反射,进而来提高性能。
我们先看下仅用反射的情况下google是如何优化的
不引入注解处理器时,Lifecycling.getCallback(observer)返回的是ReflectiveGenericLifecycleObserver
package androidx.lifecycle;
class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
@Override
public void onStateChanged(LifecycleOwner source, Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
}
这里我们主要关注回调信息 CallbackInfo 的获取方式的代码:
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
因为反射的代价是比较大的,所以又通过 ClassesInfoCache.java这个单例类,为 ReflectiveGenericLifecycleObserver 类要调用的各种方法的相关信息进行了缓存。
点进去看下它的 getInfo(...) 方法内部,是如何获取方法信息的。
CallbackInfo getInfo(Class klass) {
// 先读取缓存
CallbackInfo existing = mCallbackMap.get(klass);
if (existing != null) {
return existing;
}
existing = createInfo(klass, null);
return existing;
}
private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
// 先提取父类的 CallbackInfo
Class superclass = klass.getSuperclass();
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
if (superclass != null) {
CallbackInfo superInfo = getInfo(superclass);
if (superInfo != null) {
handlerToEvent.putAll(superInfo.mHandlerToEvent);
}
}
// 再提取接口的 CallbackInfo
Class[] interfaces = klass.getInterfaces();
for (Class intrfc : interfaces) {
for (Map.Entry<MethodReference, Lifecycle.Event> entry : getInfo(
intrfc).mHandlerToEvent.entrySet()) {
// verifyAndPutHandler 的作用是实现了接口或者覆写了父类的方法,但是添加了不同的注解事件。
verifyAndPutHandler(handlerToEvent, entry.getKey(), entry.getValue(), klass);
}
}
// 最后处理类自身的注解
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
boolean hasLifecycleMethods = false;
// 遍历方法,寻找被 OnLifecycleEvent 注解的方法
for (Method method : methods) {
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue;
}
hasLifecycleMethods = true;
// 处理参数个数,最多两个参数
Class<?>[] params = method.getParameterTypes();
int callType = CALL_TYPE_NO_ARG;
if (params.length > 0) {
callType = CALL_TYPE_PROVIDER;
if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
throw new IllegalArgumentException(
"invalid parameter type. Must be one and instanceof LifecycleOwner");
}
}
Lifecycle.Event event = annotation.value();
if (params.length > 1) {
callType = CALL_TYPE_PROVIDER_WITH_EVENT;
if (!params[1].isAssignableFrom(Lifecycle.Event.class)) {
throw new IllegalArgumentException(
"invalid parameter type. second arg must be an event");
}
if (event != Lifecycle.Event.ON_ANY) {
throw new IllegalArgumentException(
"Second arg is supported only for ON_ANY value");
}
}
if (params.length > 2) {
throw new IllegalArgumentException("cannot have more than 2 params");
}
MethodReference methodReference = new MethodReference(callType, method);
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
}
CallbackInfo info = new CallbackInfo(handlerToEvent);
// 放入缓存中
mCallbackMap.put(klass, info);
mHasLifecycleMethods.put(klass, hasLifecycleMethods);
return info;
}
这里,就能看到对注解进行处理的代码了。
我们再看下另一种优化(使用注解处理器)
首先需要在项目模块中引入
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0"
引入这个之后,会自动生成xxx_LifecycleAdapter的文件,路径为
/app/build/generated/source/apt/debug/package_name/LifeObserveCustomName_LifecycleAdapter.java
我们先看下效果:
public class LifecyclePresenter implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreateInPresenter(@NotNull LifecycleOwner owner){
System.out.println("on create");
};
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestroyInPresenter(@NotNull LifecycleOwner owner){
System.out.println("on destory");
};
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onLifecycleChangedInPresenter(@NotNull LifecycleOwner owner,
@NotNull Lifecycle.Event event){
System.out.println("on any");
}
}
上面的代码在引入注解处理器后,编译项目时就会在build目录下自动生成LifecyclePresenter_LifecycleAdapter
public class LifecyclePresenter_LifecycleAdapter implements GeneratedAdapter {
final LifecyclePresenter mReceiver;
LifecyclePresenter_LifecycleAdapter(LifecyclePresenter receiver) {
this.mReceiver = receiver;
}
@Override
public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,
MethodCallsLogger logger) {
boolean hasLogger = logger != null;
if (onAny) {
if (!hasLogger || logger.approveCall("onLifecycleChangedInPresenter", 4)) {
mReceiver.onLifecycleChangedInPresenter(owner,event);
}
return;
}
if (event == Lifecycle.Event.ON_CREATE) {
if (!hasLogger || logger.approveCall("onCreateInPresenter", 2)) {
mReceiver.onCreateInPresenter(owner);
}
return;
}
if (event == Lifecycle.Event.ON_DESTROY) {
if (!hasLogger || logger.approveCall("onDestroyInPresenter", 2)) {
mReceiver.onDestroyInPresenter(owner);
}
return;
}
}
}
这样通过该依赖库,在编译期把这些标注了的方法进行预处理,然后直接回调这些方法,避免反射,进行提高性能。
我们回头看下Lifecycling.getCallback(observer)方法中是如何判断 是代码生成还是反射调用的代码
// 获取转换type, GENERATED_CALLBACK 为使用代码生成,REFLECTIVE_CALLBACK 为使用反射调用
int type = getObserverConstructorType(klass);
// todo 详细过程暂不分析 下面简要分析下
前面已经分析过,引入注解处理器后,会生成xxx_LifecycleAdapter类,因此如果我们找到这个生成类,则认为采用代码生成方式,否则采取反射调用。
我们看下关键方法
private static int getObserverConstructorType(Class<?> klass) {
if (sCallbackCache.containsKey(klass)) {
return sCallbackCache.get(klass);
}
int type = resolveObserverCallbackType(klass);
sCallbackCache.put(klass, type);
return type;
}
private static int resolveObserverCallbackType(Class<?> klass) {
// anonymous class bug:35073837
// 匿名内部类采用反射
if (klass.getCanonicalName() == null) {
return REFLECTIVE_CALLBACK;
}
// 寻找生成类
Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);
if (constructor != null) {
// 找到生成类,则采用 GENERATED_CALLBACK
sClassToAdapters.put(klass, Collections
.<Constructor<? extends GeneratedAdapter>>singletonList(constructor));
return GENERATED_CALLBACK;
}
// 是否有方法被 OnLifecycleEvent 注解
boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
if (hasLifecycleMethods) {
// 如果有方法被 OnLifecycleEvent 注解, 则采用反射
return REFLECTIVE_CALLBACK;
}
// 如果没有找到生成类,也没有方法被 OnLifecycleEvent 注解。 我们需要去看其父类和接口,或许它们被注解,因此这里又递归调用
Class<?> superclass = klass.getSuperclass();
List<Constructor<? extends GeneratedAdapter>> adapterConstructors = null;
// 如果父类实现了 LifecycleObserver
if (isLifecycleParent(superclass)) {
if (getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) {
return REFLECTIVE_CALLBACK;
}
adapterConstructors = new ArrayList<>(sClassToAdapters.get(superclass));
}
// 如果有接口继承了 LifecycleObserver
for (Class<?> intrface : klass.getInterfaces()) {
if (!isLifecycleParent(intrface)) {
continue;
}
if (getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) {
return REFLECTIVE_CALLBACK;
}
if (adapterConstructors == null) {
adapterConstructors = new ArrayList<>();
}
adapterConstructors.addAll(sClassToAdapters.get(intrface));
}
if (adapterConstructors != null) {
sClassToAdapters.put(klass, adapterConstructors);
return GENERATED_CALLBACK;
}
return REFLECTIVE_CALLBACK;
}
因此当我们引入注解处理器后,这里将会返回GENERATED_CALLBACK
Lifecycling.getCallback(observer)方法就会把我们的LifecyclePresenter对象构建成一个 SingleGeneratedAdapterObserver对象返回(因为这里只有一个构造器,如果是多个构造器的话返回CompositeGeneratedAdaptersObserver),之后的 mLifecycleObserver.onStateChanged(owner, event);其实调用的就是SingleGeneratedAdapterObserver的onStateChanged(owner, event)方法:
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class SingleGeneratedAdapterObserver implements GenericLifecycleObserver {
private final GeneratedAdapter mGeneratedAdapter;
SingleGeneratedAdapterObserver(GeneratedAdapter generatedAdapter) {
mGeneratedAdapter = generatedAdapter;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
mGeneratedAdapter.callMethods(source, event, false, null);
mGeneratedAdapter.callMethods(source, event, true, null);
}
}
这里面就可以看到,它调用了内部包裹的类的callMethods(...)方法,也就是我们上面提到的LifecyclePresenter_LifecycleAdapter的callMethonds(...)方法。
综上,再看Lifecycling.getCallback(observer)方法就比较容易理解了。
- 如果传进来的的参数 object 是
FullLifecycleObserver类型,就把它构造成FullLifecycleObserverAdapter 对象,并返回 - 如果传进来的的参数 object 是
GenericLifecycleObserver类型,直接返回该对象 - 如果1,2都不满足,就解析该类的的构造器的Type(该类是反射获取的,还是通过注解处理器生成的)。如果是通过注解处理器生成的类来调用回调函数,就返回一个
SingleGeneratedAdapterObserver/CompositeGeneratedAdaptersObserver对象 - 如果以上条件都不满足,就通过反射来调用各回调函数。返回一个 ReflectiveGenericLifecycleObserver 对象
生命周期注册者 (LifecycleRegistry)
我们再回到LifecycleRegistry
前面已经说过LifecycleRegistry是Lifecycle的直接子类
/**
* An implementation of {@link Lifecycle} that can handle multiple observers.
* <p>
* It is used by Fragments and Support Library Activities. You can also directly use it if you have
* a custom LifecycleOwner.
*/
public class LifecycleRegistry extends Lifecycle {
//添加一个生命周期观察者(下文简称观察者),当生命周期所有者状态改变时将会进行通知.
public void addObserver(@NonNull LifecycleObserver observer) {}
//获取生命周期的当前状态.
public State getCurrentState() {}
//返回观察者的个数.
public int getObserverCount() {}
//设置当前状态并通知观察者.
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {...}
//从观察者列表中移除指定的观察者.
public void removeObserver(@NonNull LifecycleObserver observer) {...}
}
看注释知道LifecycleRegistry 本身就是一个成熟的 Lifecycle 实现类,它被实例化在Activity和Fragment中使用,如果我们需要自定义LifecycleOwner 并实现接口需要返回一个Lifecycle实例,完全可以直接在自定义LifecycleOwner中new一个LifecycleRegistry成员并返回它(简而言之就是:直接拿来用即可,上文分析普通Activity中如何实现时,就是直接用的,各位可以回头看下)。
我们先看下关于事件和状态的几个方法
public class LifecycleRegistry extends Lifecycle {
static State getStateAfter(Event event) {
//这个方法定义了Lifecycle.Event和这个方法定义了Lifecycle.State状态间的转化关系:
switch (event) {
case ON_CREATE:
case ON_STOP:
return CREATED;
case ON_START:
case ON_PAUSE:
return STARTED;
case ON_RESUME:
return RESUMED;
case ON_DESTROY:
return DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException("Unexpected event value " + event);
}
private static Event downEvent(State state) {
switch (state) {
case INITIALIZED:
throw new IllegalArgumentException();
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
case DESTROYED:
throw new IllegalArgumentException();
}
throw new IllegalArgumentException("Unexpected state value " + state);
}
private static Event upEvent(State state) {
switch (state) {
case INITIALIZED:
case DESTROYED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
case RESUMED:
throw new IllegalArgumentException();
}
throw new IllegalArgumentException("Unexpected state value " + state);
}
}
官方说请将 State 想象成一个图(graph)的节点(node),而 Event 就是这些节点之间的边(edge)。
状态之间的比较是根据Enum类的ordinal()值,即变量的声明顺序。值按照声明顺序递增。上图所示,左侧的INITIALIZED状态值为1,DESTROYED为0(因为这两个状态属于起始和结束时的状态,可以看作平级);右侧RESUMED状态值为4。
由左向右状态改变为状态提升,即upEvent;由右向左状态改变为状态下降,即downEvent。通过事件传递来改变状态,从而调用生命周期回调,完成了对生命周期的控制。
接下来看下前面遗留的最关键点 handleLifecycleEvent()方法
handleLifecycleEvent()
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
// 当我们在 LifecycleRegistry 回调 LifecycleObserver 的时候触发状态变化时,
// mHandlingEvent 为 true;
// 添加 observer 的时候,也可能会执行回调方法,这时候如果触发了状态变化,
// 则 mAddingObserverCounter != 0
if (mHandlingEvent || mAddingObserverCounter != 0) {
// 正在处理事件中或者正在处理添加 Observer 中
mNewEventOccurred = true;
// 不需要执行 sync。
// 执行到这里的情况是:sync() -> LifecycleObserver -> moveToState()
// 这里直接返回后,还是会回到 sync(),然后继续同步状态给 observer
// we will figure out what to do on upper level.
return;
}
// 标记正在处理事件
mHandlingEvent = true;
// sync() 会把状态的变化转化为生命周期事件,然后转发给 LifecycleObserver
sync();
mHandlingEvent = false;
}
/**
* Custom list that keeps observers and can handle removals / additions during traversal.
* Invariant: at any moment of time for observer1 & observer2:
* if addition_order(observer1) < addition_order(observer2), then
* state(observer1) >= state(observer2),
*
* Invariant的规定:无论何时,先加入的observer的state值要大于后加入的observer的状态值
* 这个规定影响了sync的实现
*/
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
private void sync() {
// 使用弱应用持有 LifecycleOwner,也是为了防止 Activity/Fragment 内存泄漏
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch new events from it.");
return;
}
while (!isSynced()) {
// mNewEventOccurred 是为了在 observer 触发状态变化时让 backwardPass/forwardPass()
// 提前返回用的。我们刚准备调他们,这里设置为 false 即可。
mNewEventOccurred = false;
//参照上文Invariant的规定,先加入的observer的state值一定要大于或等于后加入的observer的state值
//那么在mObserverMap中,eldest(即队头)的state最大,newest(即队尾)的state最小。如果当前mState小于eldest的state值,说明mObserverMap中的值需要更新
// 为了维持 mObserverMap 的 Invariant,这里我们需要从队尾往前更新元素的状态
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
// 最先添加的 observer 的状态大于当前状态,回退
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
// 如果 mNewEventOccurred,说明在上面调用 backwardPass() 时,客户触发了状态修改
// 有新的事件发生,则放弃这次同步,延迟到下一次
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
// 最新添加的 observer 如果状态一致,则可以乐观地表示在它之前添加的 observer 状态也是一致的
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
// 如果所有的 observer 的状态都已经同步完,则返回 true
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
// eldest 最先添加的,newest 最新添加的
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
// 因为我们保证队头的 state >= 后面的元素的 state,所以只要判断头尾就够了
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
sync() 的主要作用就是把 mObserverMap 里所有元素的状态都同步为 mState。
这里分为两种情况,一种是需要回退状态(backward),另外一种则是需要前进(forward),其中 backward 代码如下:
private void backwardPass(LifecycleOwner lifecycleOwner) {
// 使用 eldest(start) 判断是否需要回退
// 降序迭代,end -> start
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
while (descendingIterator.hasNext() && !mNewEventOccurred) {
// mNewEventOccurred 判断是否有新事件分发
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
// 回退
// 举个例子:observer.state 为 RESUMED
// mState 为 CREATED
// downEvent(observer.state) 为 ON_PAUSE
Event event = downEvent(observer.mState);
// getStateAfter(event) 为 STARTED
// 最终:RESUMED -> STARTED,在下一次同步中再同步为 CREATED
// pushParentState 和 popParentState 则是将 state 暂存在 List 中
// 这个作用我们会在 addObserver 中讲
pushParentState(getStateAfter(event));
// 分发事件
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
在看这个方法时,可以参考上面的状态图。比方说,假设当前队列里的元素都处于 CREATED。接着收到了一个 ON_START 事件,从图里面可以看出,接下来应该是要到 STARTED 状态。由于 STARTED 大于 CREATED,所以会执行 forwardPass()。forwardPass() 里面调用 upEvent(observer.mState),返回从 CREATED 往上到 STARTED 需要发送的事件,也就是 ON_START,于是 ON_START 事件发送给了客户。
还有注意下 backwardPass() 的逻辑是将较大的状态逐步回退。为什么说是逐步呢?比如 observer.state 是 RESUMED,当前状态是 CREATED,那这里会分两次回退,分别为:RESUMED -> STARTED 和 STARTED -> CREATED
forwardPass() 逻辑类似,则不分析了。
上图可以看到,通过 mObserverMap 最终获取到一个 ObserverWithState 类型的 observer 对象,并调用它的dispatchEvent进行事件分发
继续看ObserverWithState 它是 LifecycleRegistry 的一个静态内部类。
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//getCallback就是用来转换LifecycleObserver的 详细分析见上文
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
从名称上就能看出,该类封装了 Observer 对象和 State 对象(具体就是 State 和 GenericLifecycleObserver,GenericLifecycleObserver 是个接口,继承自 LifecycleObserver),在其 dispatchEvent 方法中,最终会回调 mLifecycleObserver 的 onStateChanged(...)方法。
追踪到这里,我们知道了,Lifecycle在监听到生命周期变化之后,最终会回调 GenericLifecycleObserver# onStateChanged() 方法。
到这里我们先梳理一遍流程(以Fragment为例),
-
Fragment实现LifecycleOwner接口,提供一个LifecycleRegistry实例 -
在
Fragment的各个生命周期内,调用LifecycleRegistry.handleLifecycleEvent(event)方法分发生命周期event -
LifecycleRegistry.handleLifecycleEvent(event)会从mObserverMap取出ObserverWithState进行各种同步操作,在同步过程中,会调用ObserverWithState#dispatchEvent方法将生命周期event分发出去 -
handleLifecycleEvent方法会通过getStateAfter获取当前应处的状态的下一状态,然后通过moveToState方法修改当前状态值,然后调用sync方法通知了生命周期观察者,也就是我们实现了LifecycleObserver接口的类在
sync方法中,通过对比当前状态和上一状态来完成当前State的状态更新,在forwardPass和backwardPass方法中会从mObserverMap取出ObserverWithState元素,一个一个的同步,同步中就可以看到事件派发方法了,ObserverWithState内部类的dispatchEvent方法。
现在就剩一个问题了,mObserverMap中的元素是怎么存进去的,我有查看下mObserverMap的调用之处,发现只有一个地方,那就是addObserver方法中
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// ...
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
// ...
}
而这个方法正好就是我们在Fragment中调用的
getLifecycle().addObserver(mObserver);
至此,总算跟我们的 MyObserver 关联上了,整个流程就连通啦。
最后再看下addObserver方法
addObserver
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
//todo 这段注释要再理解下
// 上文在dispatchEvent前后进行的pushParentState和popParentState就是为了解决这个问题:
// 如果在onStart中注销了observer又重新注册,这时重新注册的observer初始的状态为INITIALIZED;
// 而如果想执行ON_START的对应回调,需要newObserver处于CREATED状态(之前的状态因为removeObserver,不存在于mObserverMap中)
// mParentStates的作用就是为newObserver提供了CREATED这个状态
// 如果不是 DESTROYED,则从 INITIALIZED 开始分发
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// ObserverWithState 用于分发事件给 observer
// ObserverWithState 里会做 Observer 的转换
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 放入 map 中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
// isReentrance 表示是否在分发事件时新添加了 observer
// 举个例子:在 observer 在 onStart() 中又调用了 addObserver()
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 引入 parentState, targetState 等都是为了保证列表中后加的 Observer 的状态不能大于前面的, 这样做之后,如果列表第一个和最后一个的状态和 LifecycleRegistry.mState 相等时,就说明状态同步完成了。
// 计算需要分发的状态
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// 将事件逐步分发到 targetState
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
// 如果 statefulObserver.state 小于 targetState
pushParentState(statefulObserver.mState);
// 如果 state 为 STARTED,则 upEvent(state) 则为 ON_RESUME
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
//addObserver()主要考虑了 Reentrance 的情况,即在observer的事件分发中,又添加了新的 observer的情况。
if (!isReentrance) {
// we do sync only on the top level.
// 当前为重入,则不进行同步
sync();
}
mAddingObserverCounter--;
}
private State calculateTargetState(LifecycleObserver observer) {
// 获取上一个添加的 observer
Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
State siblingState = previous != null ? previous.getValue().mState : null;
// mParentStates 是个 List,它的添加和删除分别由 pushParentState() 和 popParentState(),它们是成对出现的,在 dispatchEvent 的前后
// 在这种 case 下,会存在 parentState:在 dispatchEvent 时,又调用了 addObserver(),即上面说的 isReentrance
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
// 这里的计算是获取更合适的状态
// 考虑以下这种 case:某个 observer 在 onStart() 中再调用 addObserver,那这个 observer 理应使用 STARTED 状态分发,而当前状态即 mState 可能是 RESUMED,再在 sync() 中进行同步
return min(min(mState, siblingState), parentState);
}
addObserver 并不是简单的将 Observer 加入 map 中, 首先它会做上文提到的 Observer 转换。 其次需要考虑“重入问题”。 所谓的“重入问题”,就是 addObserver 会触发 Observer 生命周期函数的调用,而 Observer 在生命周期函数中又调用了 addObserver 等方法。 因此, LifecycleRegistry 用变量 mAddingObserverCounter 和 mHandlingEvent 来判断是否处于重入状态。
其他 LifecycleOnwer
LifecycleService
ServiceLifecycleDispatcher 将事件派发重新推到主线程消息队列,用于保证确保回调在 Service 生命周期回调后再调用。
ProcessLifecycleOwner
用于监听整个应用的前后台切换。也是利用 ActivityLifecycleCallback 监听每个 Activity 的生命周期,如果 onStop 事件后,没有监听到任意的 onStart 事件,那么 ProcessLifecycleOwner 就会认为整个应用切换到后台,同时留下一个标志。如果监听到 onStart 事件,同时检查有标志那么就会认为应用回到前台。
linxiaotao.github.io/2019/01/14/…]
【奇技淫巧】使用 ProcessLifecycle 优雅地监听应用前后台切换 todo
其他
todo 下面这段可以放到其他文章去
能感知生命周期的组件的最佳实践
- 尽量让您的 UI 控制器(activity 和 fragment)别什么都自己扛着。它们不应试图获取自身的数据,而是应该通过
ViewModel,并观察一个LiveData对象来在视图上针对变动做出反应。 - 尝试编写数据驱动的 UI,并让您的 UI 控制器负责在数据变化的时候更新视图、或者把用户的行为通知给
ViewModel。 - 将您的数据逻辑放入
ViewModel类。ViewModel应当充作您的 UI 控制器和应用其余部分的连接。请小心注意:获取数据(比如从网络下载)并不是ViewModel的责任,恰恰相反,ViewModel应当调用合适的组件去获取数据,再将结果提供给 UI 控制器。 - 使用数据绑定来在您的视图和 UI 控制器之间维持整洁的接口。这有利于让您的视图更具陈述性,而且让您在 UI 控制器中只需添加最少的更新逻辑。如果您更愿意使用 Java 语言来进行数据绑定,使用诸如 Butter Knife 的库可以避免八股代码而获得更好的抽象。
- 如果您的 UI 很复杂,请考虑创建一个 presenter 类来处理 UI 修改。这可能会比较累人,但可以让您的 UI 组件更易于测试。
- 避免在您的
ViewModel中直接引用View或Activity等 context。如果ViewModel比其 activity 还活得长久(比如配置变更),您的 activity 就内存泄漏了,很难被 GC 得当回收。
能感知生命周期的组件的用例
能感知生命周期的组件能让许多用例中的生命周期管理变得简单。以下是几个例子:
- 切换地理位置更新的精度。当您的应用可见时,启动高精度的地理位置更新;当您的应用进入后台时,切换成低精度的更新。
LiveData就是一个能感知生命周期的组件,让您的应用在用户移动的时候自动更新 UI。 - 开始和停止视频缓冲。尽快开始视频缓冲,但把回放延迟到应用完全启动之后。您还可以使用这样的组件来在应用被销毁时停止视频缓冲。
- 开始和停止网络连接。当应用在前台时,开启使用网络连接的流媒体;当应用在后台时自动暂停。
- 暂停和恢复动画 drawable。当应用进入后台时,处理动画 drawable 的暂停;当应用回到前台时,恢复动画。
处理 onStop 事件
当 Lifecycle 属于一个 AppCompatActivity 或 Fragment,Lifecycle 的状态会变为 CREATED,而 ON_STOP 事件会在 AppCompatActivity 或 Fragment 的 onSaveInstanceState() 被调用时分发。
当一个 Fragment 或 AppCompatActivity 的状态在 onSaveInstanceState() 中保存时,直到 ON_START 触发之前,其 UI 被认为是不可变动的。试图在状态保存后更改 UI 可能会导致您的应用产生不一致的导航状态,这就是为什么当应用在状态保存之后试图执行 FragmentTransaction 时,FragmentManager 会抛出异常。欲了解更多信息,请参阅 commit()。
LiveData 提供了对这种边缘情况的开箱即用的支持:如果观察者所联系的 Lifecycle 连 STARTED 都不是的话,它就不会调用该观察者。其内部实现是先调用 isAtLeast() 来决定是否要触发其观察者。
悲剧的是,AppCompatActivity 的 onStop() 是在 onSaveInstanceState() 之后调用的,这导致了一段 UI 不允许改动、但 Lifecycle 还没进入 CREATED 状态的间隙。
为了防止这样的悲剧,beta2 及更低版本的 Lifecycle 将状态标记为 CREATED 但并不分发事件,这样一来任何检查当前状态的代码都会得到真正的值,尽管直到系统调用 onStop() 之前事件都没被分发。
二次悲剧的是,这种解决方案有两个主要的问题:
- 在 23 及更低的 API 版本上,一个 activity 即使被另一个 activity 部分遮挡,Android 系统实际上也会保存其状态。换言之,Android 系统调用了
onSaveInstanceState(),但并不一定调用onStop()。这导致了一个可能很长的间隙,期间观察者仍然认为生命周期是活动的,但其实 UI 状态不能改动。 - 任何想要把类似行为暴露给
LiveData的类都需要实现beta2或更低版本的Lifecycle所提供的变通方案。
注意:为了让上述流程更简单、向后兼容性更好,从 1.0.0-rc1 版本开始,Lifecycle 对象会被标记为 CREATED,而 ON_STOP 会在 onSaveInstanceState() 被调用时分发、毋须等待 onStop 方法被调用。这应该不太会影响您的代码,但您仍然需要了解,因为它和 26 及更高版本的 API 中 Activity 方法的调用顺序并不一致。
以上是来自官方文档的翻译,翻译地址见参考一。
参考
Android官方架构组件Lifecycle:生命周期组件详解&原理分析
Android arch components 源码分析(2)—— Lifecycle