Android生命周期感应组件lifecycle

背景

生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您写出更有条理且往往更精简的代码,这样的代码更易于维护。

一种常见的模式是在 Activity 和 Fragment 的生命周期方法中实现依赖组件的操作。但是,这种模式会导致代码条理性很差而且会扩散错误。通过使用生命周期感知型组件,您可以将依赖组件的代码从生命周期方法移入组件本身中。

androidx.lifecycle 软件包提供了可用于构建生命周期感知型组件的类和接口 - 这些组件可以根据 Activity 或 Fragment 的当前生命周期状态自动调整其行为。
导入方法

在 Android 框架中定义的大多数应用组件都存在生命周期。生命周期由操作系统或进程中运行的框架代码管理。它们是 Android 运作方式的核心,应用必须遵循它们。如果不这样做,可能会引发内存泄露甚至应用崩溃。

假设我们有一个在屏幕上显示设备位置的 Activity。常见的实现可能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
}
}

虽然此示例看起来没问题,但在真实的应用中,最终会有太多管理界面和其他组件的调用,以响应生命周期的当前状态。管理多个组件会在生命周期方法(如 onStart() 和 onStop())中放置大量的代码,这使得它们难以维护。

androidx.lifecycle 软件包提供的类和接口可帮助您以弹性和隔离的方式解决这些问题。

Lifecycle

Lifecycle 是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。

Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:

  • 事件
    从框架和 Lifecycle 类分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。
  • 状态
    由 Lifecycle 对象跟踪的组件的当前状态。

构成 Android Activity 生命周期的状态和事件

Lifecycle源代码如下,可以看出下Lifecycle类主要是3个方法,分别是:添加observer、移除observer以及获取当前的状态,然后类里面有关于Event和State的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public abstract class Lifecycle {
/**
* Adds a LifecycleObserver that will be notified when the LifecycleOwner changes
* @param observer The observer to notify.
*/
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);

/**
* Removes the given observer from the observers list.
* @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();

@SuppressWarnings("WeakerAccess")
public enum Event {
/**
* Constant for onCreate event of the {@link LifecycleOwner}.
*/
ON_CREATE,
/**
* Constant for onStart event of the {@link LifecycleOwner}.
*/
ON_START,
/**
* Constant for onResume event of the {@link LifecycleOwner}.
*/
ON_RESUME,
/**
* Constant for onPause event of the {@link LifecycleOwner}.
*/
ON_PAUSE,
/**
* Constant for onStop event of the {@link LifecycleOwner}.
*/
ON_STOP,
/**
* Constant for onDestroy event of the {@link LifecycleOwner}.
*/
ON_DESTROY,
/**
* An {@link Event Event} constant that can be used to match all events.
*/
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 类的 addObserver() 方法并传递观察者的实例来添加观察者,如以下示例中所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}

myLifecycleOwner.getLifecycle().addObserver(new MyObserver());

在上面的示例中,myLifecycleOwner 对象实现了 LifecycleOwner 接口 ,接下来讲一下LifecycleOwner接口:

LifecycleOwner

首先来看下LifecycleOwner接口的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* A class that has an Android lifecycle. These events can be used by custom components to
* handle lifecycle changes without implementing any code inside the Activity or the Fragment.
*
* @see Lifecycle
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}

Android源码中,Activity以及Fragment均实现了这个LifecycleOwner接口,这样使用就非常简单了,直接使用getLifecycle().addObserver(new MyObserver())就可以把Observer注册到Lifecycle上,自动感应生命周期了。

生命周期自动感应原理解析

那么问题来了,fragment或者activity是怎么把自身的生命周期分发给每一个Observer的呢?生命周期自动感应是怎么工作的呢?我们通过解析源码来找到答案。

查看SupportActivity的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class SupportActivity extends Activity implements LifecycleOwner, Component {
private SimpleArrayMap<Class<? extends SupportActivity.ExtraData>,
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

public SupportActivity() {
}

protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}

@CallSuper
protected void onSaveInstanceState(Bundle outState) {
this.mLifecycleRegistry.markState(State.CREATED);
super.onSaveInstanceState(outState);
}

public Lifecycle getLifecycle() {
return this.mLifecycleRegistry;
}
}

可以看出在activity的onCreate方法调用了一个方法: ReportFragment.injectIfNeededIn(activity),接下来看下这个init做了什么事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "android.arch.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();
}
}

@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 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);
}
}
}
}

这个代码就比较清晰了:在activity上面挂了一个ReportFragment专门用来感应activity的生命周期,把activity的生命周期分发给activity里面的Lifecycle,其中activity里面的Lifecycle是一个LifecycleRegistry对象。通过这种方式就完成了activity生命周期到Lifecycle的转发。

到这里大家可能会有一个疑问了:那么fragment的生命周期是怎么感应的呢?因为fragment的生命周期是可能比activity的生命周期要短的,这个我们从fragment源码中寻找答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void performStart() {
..........
this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_START);
if (this.mView != null) {
this.mViewLifecycleRegistry.handleLifecycleEvent(Event.ON_START);
}
}

void performResume() {
..............
this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
if (this.mView != null) {
this.mViewLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
}
}

可以看出fragment中生命周期是主动转发的,主动调用LifecycleRegistry的方法进行转发。

至此,activity和fragment的生命周期转发机制已经了解清楚了,接下来我们看下LifecycleRegistry是怎么把生命周期进一步转发给LifecycleObserver的。

LifecycleRegistry源码解析

上面说了activity和fragment里面都持有LifecycleRegistry,通过这个类来进行生命周期转发,接下来对LifecycleRegistry源码进行解析:

添加观察者:

添加观察者通过addObserver方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//把传入的observer封装成一个ObserverWithState对象
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//如果之前已经有这个observer,就直接返回
if (previous != null) {
return;
}
//获取到LifecycleOwner
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
/**是否是可重入的,什么意思呢?这里有两个判断条件:
1、mAddingObserverCounter !=0,什么时候会满足这个条件呢,就是在下面的statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));方法里面可能又会调用addObserver,这次addObserver的时候这个mAddingObserverCounter就不为0了
2、mHandlingEvent为true代表正在进行状态转移

isReentrance这个值主要是为了防止重复调用sync方法,在嵌套的情况下,保证只有最上层最后调用这个sync方法,这个下面也有注释说明
**/
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//计算出目标的State
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//如果observer目前呢的state小于要转移的targetState,那么就要进行state转移,比如目前页面的state状态为CREATED,但是oberver.mState初始化的状态是INITIALIZED,那么就要把状态转移到CREATED
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
//upEvent方法就是把state转移到下一个生命周期Event,然后再把这个Event通知给oberver进行分发,然后在这个
//statefulObserver内部会根据这个Event更新自己的mState

//这里每次只能进行一个Event转移,就比如说现在页面的state状态为STARTED,那么就需要进行两次转移,也就是这个这个while循环会执行2次,相应的observer会先后收到ON_CREATE和ON_START回调
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
//再次计算targetState,判断observer.mState是否达到了targetState,这里是一个while循环,直到达到了
//targetState才会退出
targetState = calculateTargetState(observer);
}

if (!isReentrance) {
// we do sync only on the top level.
//把当前页面的state状态同步给所有的oberver
sync();
}
mAddingObserverCounter--;
}

可以看出addObserver主要是分为几个步骤:

1、把传入的observer封装成一个ObserverWithState对象,保存到一个map里面,key值就是这个observer。我们来看下ObserverWithState的构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;

ObserverWithState(LifecycleObserver observer, State initialState) {
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;
}
}

在构造方法里面会通过Lifecycling.getCallback(observer)方法把observer转换为一个GenericLifecycleObserver对象。刚刚上面说了类可以通过向其方法添加注解来监控组件的生命周期状态,这个Lifecycling.getCallback方法里面就是会去读取每个LifecycleObserver对象方法上面的注解,然后转换成对应的GenericLifecycleObserver:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
static GenericLifecycleObserver getCallback(Object object) {
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}

if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}
//根据注解生成对应的GenericLifecycleObserver ,一般不推荐这种方式
final Class<?> klass = object.getClass();
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直接实现FullLifecycleObserver或者GenericLifecycleObserver接口,如果没有实现这两个接口,继续往下走的话就是注解相关处理,然后包装生成对应的GenericLifecycleObserver子类,一般情况下不推荐这种方式,因为涉及到runtime反射,会有一定的性能开销。最佳操作是如果工程支持java8的话,可以实现DefaultLifecycleObserver接口,子类根据自身需求实现对应的方法(不得不说default真是个好东西啊~~):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface DefaultLifecycleObserver extends FullLifecycleObserver {

@Override
default void onCreate(@NonNull LifecycleOwner owner) {
}

@Override
default void onStart(@NonNull LifecycleOwner owner) {
}

@Override
default void onResume(@NonNull LifecycleOwner owner) {
}

@Override
default void onPause(@NonNull LifecycleOwner owner) {
}

@Override
default void onStop(@NonNull LifecycleOwner owner) {
}

@Override
default void onDestroy(@NonNull LifecycleOwner owner) {
}
}

ObserverWithState对象封装好了之后,继续往下走:

2、根据当前页面state对observer进行state转移,这里可能会涉及到多次转移

3、把当前页面的state状态同步给所有的oberver

移除观察者

移除观察者通过removeObserver方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void removeObserver(@NonNull LifecycleObserver observer) {
// we consciously decided not to send destruction events here in opposition to addObserver.
// Our reasons for that:
// 1. These events haven't yet happened at all. In contrast to events in addObservers, that
// actually occurred but earlier.
// 2. There are cases when removeObserver happens as a consequence of some kind of fatal
// event. If removeObserver method sends destruction events, then a clean up routine becomes
// more cumbersome. More specific example of that is: your LifecycleObserver listens for
// a web connection, in the usual routine in OnStop method you report to a server that a
// session has just ended and you close the connection. Now let's assume now that you
// lost an internet and as a result you removed this observer. If you get destruction
// events in removeObserver, you should have a special case in your onStop method that
// checks if your web connection died and you shouldn't try to report anything to a server.
mObserverMap.remove(observer);
}

可以看出removeObserver只做了一件事,就是把observer从map里面移除。

生命周期转发

当生命周期发生改变的时候,会调用handleLifecycleEvent方法进行分发,里面调用moveToState方法进行状态转移,同步给所有的observer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}

private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}

通过以上这3个方法就完成了生命周期->oberver的转发,实现了生命周期的自动监听实现。

自定义LifecycleOwner

如果您有一个自定义类并希望使其成为 LifecycleOwner,您可以使用 LifecycleRegistry 类,但需要将事件转发到该类,如以下代码示例中所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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;
}
}

总结

Lifecycle组件实际上就是对activity或者fragment的生命周期进行自动化监听,然后业务方根据自己的需求可以往Lifecycle组件里面在add或者remove监听,就是一种典型的观察者模式,去掉了以往需要直接在acivity和fragment的生命周期方法中显示调用组件对应方法的过程,让组件代码更有条理,也避免了activity和fragment的代码膨胀,提升代码的可维护性。