Android Jetpack之Lifecycles

Android Jetpack之Lifecycles

Android中大多数的组件都有生命周期函数,生命周期由操作系统或者framework层的代码来管理,它们是Andorid的核心运行方式。我们平时写程序必须遵循生命周期的原则,否则会造成内存泄露甚至程序崩溃

我们通常会在activity和fragment的生命周期函数内来做一些初始化操作和释放资源的一些操作,但是这样会导致代码组织不良,容易出错,使用生命周期感知组件,可以让生命周期方法移动到组件上来。

android.arch.lifecycle包中提供了一些类和接口来构建生命周期组件,它们可以根据activity和fragment的生命周期的当前状态自动调整自身行为。

在没有使用生命周期感知组件之前,如果我们想要使用定位服务,我们可能会按照下面的方式来写,通过一个接口来回调

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

class MyListener {
public MyListener() {
// ...
}

void start() {
// 连接到系统位置服务
}

void stop() {
// 断开连接
}
}

class MyActivity extends AppCompatActivity {
private MyListener myListener;

@Override
public void onCreate(...) {
myListener = new MyListener(this, (location) -> {
//更新UI
});
}

@Override
public void onStart() {
super.onStart();
myListener.start();
//如果有其他组件需要监听生命周期,在下面继续回调
}

@Override
public void onStop() {
super.onStop();
myListener.stop();
//如果有其他组件需要监听生命周期,在下面继续回调
}
}

上面的写法是可以的,但是考虑到假如除了定位服务还有一些别的服务也需要在这个activity的生命周期函数内执行,比如网络,比如媒体查询,这时候,onStart()和onStop()这两个方法内会有很多的接口回调不利于维护。

另外还会有一些别的问题,比如执行onStop()的时候,初始化还没完成,而我们又在初始化之后做了一些耗时的操作,这就会导致资源不能及时的关闭或者断开。我们可能需要在初始化完成后来检查其所依赖的activity的状态来避免这个问题。

lifecycle组件可以很灵活的处理这些问题。

lifecyle的导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 //如果没用AndroidX
implementation "android.arch.lifecycle:runtime:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

//如果用了AndoridX
def lifecycle_version = "2.0.0"
// 包含 ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
//只包含 ViewModel 如果是 Kotlin 使用 lifecycle-viewmodel-ktx
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// 只包含 LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// 只包含Lifecycles
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
//注解处理器,如果是Kotlin 使用 kapt 代替 annotationProcessor
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
//如果使用了Java8, 使用下面的代替lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

lifecycle是一个类,它包含一些生命周期组件的生命周期的信息比如activity和fragment,并允许其他的对象监听此状态

它主要使用两个枚举类来监听它所关联的组件的生命周期

  • Event: 这些events是从系统框架层(framework )和 Lifecycle类中派发的,他们映射到 activities 和 fragments 中的回调中。
  • State:由Lifecycle对象来跟组组件的当前状态。

LifecycleOwner是一个单一的方法接口,表示该类有一个Lifecycle,它有一个方法, getLifecycle()必须由类实现,该方法可以获取生命周期比如activity和fragment的生命周期,任何自定义的类都可以实现这个接口。

使用LifecycleObserver可以和LifecycleOwner无缝对接,LifecycleOwner 相当于被观察者,LifecycleObserver相当于观察者,LifecycleOwner可以获取组件的生命周期,那么观察者也能观察生命周期的变化了。

在Support Library 26.1.0 和以上的版本中,activity和fragment已经默认实现了LifecycleOwner接口,如果是26.1.0以下版本需要自定义实现LifecycleOwner接口。

比如一开始的例子,可以让MyLocationListener实现LifecycleObserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

public class MyListener implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
// 连接到服务
Log.i("LifecycleEvent","start");
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
// 断开连接
Log.i("LifecycleEvent","stop");
}
}

public class LifeActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLifecycle().addObserver(new MyListener());
}
}

通过上面的实现,MyListener类就可以感知生命周期了,以后所有的初始化和释放的操作它都可以自己完成,查看log日志可以看到MyListener已经可以感知到生命周期了

1
2
04-08 16:43:49.144 11995-11995/com.chs.androiddailytext I/LifecycleEvent: start
04-08 16:43:50.873 11995-11995/com.chs.androiddailytext I/LifecycleEvent: stop

MyListenr除了实现LifecycleObserver然后使用注解,也可以继承DefaultLifecycleObserver然后实现里面的方法。因为Java8之后注解的方式会被弃用,所以推荐使用DefaultLifecycleObserver

1
2
3
4
5
6
7
/**
* Callback interface for listening to {@link LifecycleOwner} state changes.
* <p>
* If you use Java 8 language, <b>always</b> prefer it over annotations.
*/
@SuppressWarnings("unused")
public interface DefaultLifecycleObserver extends FullLifecycleObserver {......}

Lifecycle的实现原理: 本文使用的API28

它其实就是一个观察者模式,LifecycleOwner是被观察者,在Support Library 26.1.0 和以上的版本中,activity和fragment已经默认实现了LifecycleOwner接口,所以他俩都是被观察者,我们自己定义的LifecycleObserver就是观察者, 通过getLifecycle().addObserver方法注册观察者。

下面从getLifecycle()这个方法开始查看源码

1
2
3
4
5
6
7
8
9
  //在FragmentActivity中,FragmentActivity继承自ComponentActivity(本文使用的API28)
public Lifecycle getLifecycle() {
return super.getLifecycle();
}
//在ComponentActivity 中
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

getLifecycle()方法返回了一个LifecycleRegistry对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class LifecycleRegistry extends Lifecycle {
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
}
public class ComponentActivity extends Activity
implements LifecycleOwner, KeyEventDispatcher.Component {
......
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
......
}

LifecycleRegistry对象继承自Lifecycle,是从ComponentActivity中直接new出来的,并传入一个LifecycleOwner对象。ComponentActivity实现了LifecycleOwner接口所以传入自己就好了。

ComponentActivity中除了创建了LifecycleRegistry对象外在其onCreate方法中还执行了ReportFragment.injectIfNeededIn(this)这个方法。

下面来看看这个ReportFragment

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
113
114
/**
* 分派初始化事件的内部类。
* @hide
*/
@SuppressWarnings("UnknownNullness") // TODO https://issuetracker.google.com/issues/112197238
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
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();
}
}

通过上面的代码我们可以知道:

  • injectIfNeededIn方法用来创建这个ReportFragment,并且将它commit到当前的Activity中。这是一个没有布局文件的空的Fragment,虽然没有布局文件,但是它有一个完整的生命周期,我们可以把它的生命周期利用起来。
  • 在其生命周期方法中调用dispatch(Lifecycle.Event event)方法,传入对应的event,Event是一个枚举类,里面定义了生命周期函数名字对应的标志位常量。比如onStart()中就传入Lifecycle.Event.ON_RESUME。
  • dispatch方法中调用了getLifecycle().handleLifecycleEvent(event),前面我们知道getLifecycle()返回的是一个LifecycleRegistry对象,已经在Activity成员变量中new了出来。
  • 注意:在onActivityCreated,onStart,onResume方法中除了调用dispatch方法还是调用了dispatchCreate,dispatchStart,dispatchResume方法。这些先略过最后在看。
1
2
3
4
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}

handleLifecycleEvent方法的作用就是,设置当前状态并通知观察者,下面来看getStateAfter和moveToState方法

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
static State getStateAfter(Event event) {
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 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;
}

从getStateAfter中找出当前的需要赋值的状态,然后赋值给成员变量mState。

状态赋值完之后调用了sync()方法,下面看这个方法

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
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}

isSynced()方法,用来判断最后添加的观察者和最新添加的观察者的状态是否一致,并且当前将要分发的事件状态和最新添加的观察者的状态是否一致。

如果一致执行backwardPass方法和forwardPass方法,两个方法都是循环遍历观察者的集合分发事件,正常情况下执行backwardPass方法,如果在执行backwardPass方法的过程中有新的状态改变,会执行forwardPass方法。

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
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
while (descendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
popParentState();
}
}
}

可以看到这两个方法中都是循环观察者的集合,调用观察者(observer)的dispatchEvent方法来分发事件。这个观察者是一个ObserverWithState对象

观察者的集合是咋来的呢,Ok,现在回到Activity中getLifecycle().addObserver(new MyListener());,前面我们都是跟着getLifecycle()走的,现在看addObserver这个添加观察者的方法。

addObserver是Lifecycle这个接口中的方法,LifecycleRegistry实现了Lifecycle接口,着getLifecycle()方法返回一个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
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
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;
}

boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
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);
}

if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}

上面代码最主要的就是封装一个ObserverWithState对象,然后保存到一个自定义的Map集合中。前面我们知道backwardPass和forwardPass方法中都是当状态改变的时候,循环调用的ObserverWithState中的dispatchEvent方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}
}

  • 构造方法中,把我们传入的LifecycleObserver对象通过lifecycleEventObserver方法转换成一个LifecycleEventObserver对象,
  • LifecycleEventObserver也是一个接口,只有一个方法onStateChanged。它有好几个子类,比如我们的MyListener实现了LifecycleObserver接口,那么它会转化成SingleGeneratedAdapterObserver,如果我们的MyListener实现了DefaultLifecycleObserver接口,就会转化成FullLifecycleObserverAdapter。
  • 事件分发方法dispatchEvent中调用onStateChanged通知状态改变了。

到这里观察和监听的一个闭环就完成了

现在回到ReportFragment中,前面在看其生命周期方法的时候看到在onActivityCreated,onStart,onResume方法中除了调用dispatch方法还是调用了dispatchCreate,dispatchStart,dispatchResume方法。为啥呢?

因为这个ReportFragment是在ComponentActivity这个Activity中的onCreate方法中创建的,ComponentActivity继承自Activity假如我们的Activity也直接继承自Activity,那没法初始化ReportFragment,怎么监听生命周期呢?

跟进这几个方法看看

1
2
3
4
5
private void dispatchCreate(ActivityInitializationListener listener) {
if (listener != null) {
listener.onCreate();
}
}

调用了ActivityInitializationListener的相关方法,前面贴的ReportFragment的代码最后可以看到ActivityInitializationListener是一个接口,里面有onCreate,onStart,onResume方法,ReportFragment中还提供了一个set方法。studio中点击这个set方法,进入到新大陆

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
public class ProcessLifecycleOwner implements LifecycleOwner {

@VisibleForTesting
static final long TIMEOUT_MS = 700; //mls

// ground truth counters
private int mStartedCounter = 0;
private int mResumedCounter = 0;

private boolean mPauseSent = true;
private boolean mStopSent = true;

private Handler mHandler;
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);

private Runnable mDelayedPauseRunnable = new Runnable() {
@Override
public void run() {
dispatchPauseIfNeeded();
dispatchStopIfNeeded();
}
};

ActivityInitializationListener mInitializationListener =
new ActivityInitializationListener() {
@Override
public void onCreate() {
}

@Override
public void onStart() {
activityStarted();
}

@Override
public void onResume() {
activityResumed();
}
};

private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();

/**
* The LifecycleOwner for the whole application process. Note that if your application
* has multiple processes, this provider does not know about other processes.
*
* @return {@link LifecycleOwner} for the whole application.
*/
@NonNull
public static LifecycleOwner get() {
return sInstance;
}

static void init(Context context) {
sInstance.attach(context);
}

void activityStarted() {
mStartedCounter++;
if (mStartedCounter == 1 && mStopSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mStopSent = false;
}
}

void activityResumed() {
mResumedCounter++;
if (mResumedCounter == 1) {
if (mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mPauseSent = false;
} else {
mHandler.removeCallbacks(mDelayedPauseRunnable);
}
}
}

void activityPaused() {
mResumedCounter--;
if (mResumedCounter == 0) {
mHandler.postDelayed(mDelayedPauseRunnable, TIMEOUT_MS);
}
}

void activityStopped() {
mStartedCounter--;
dispatchStopIfNeeded();
}

void dispatchPauseIfNeeded() {
if (mResumedCounter == 0) {
mPauseSent = true;
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
}

void dispatchStopIfNeeded() {
if (mStartedCounter == 0 && mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
mStopSent = true;
}
}

private ProcessLifecycleOwner() {
}

void attach(Context context) {
mHandler = new Handler();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
Application app = (Application) context.getApplicationContext();
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(mInitializationListener);
}

@Override
public void onActivityPaused(Activity activity) {
activityPaused();
}

@Override
public void onActivityStopped(Activity activity) {
activityStopped();
}
});
}

@NonNull
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
}

从注释里可以看到,该类为整个应用程序过程提供生命周期。在它的attach方法中,通过registerActivityLifecycleCallbacks方法注册了监听了程序的生命周期。在onActivityCreated方法中可以看到给ReportFragment设置了mInitializationListener。

attach方法在哪里调用的呢

1
2
3
4
5
private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();

static void init(Context context) {
sInstance.attach(context);
}

调用了一个静态的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
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}

@Nullable
@Override
public Cursor query(@NonNull Uri uri, String[] strings, String s, String[] strings1,
String s1) {
return null;
}

@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}

@Nullable
@Override
public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
return null;
}

@Override
public int delete(@NonNull Uri uri, String s, String[] strings) {
return 0;
}

@Override
public int update(@NonNull Uri uri, ContentValues contentValues, String s, String[] strings) {
return 0;
}
}

这里我们看到了初始化的地方,ProcessLifecycleOwnerInitializer继承自ContentProvider,Lifecycle自动在我们的AndroidManifest.xml中添加了一个ContentProvider,用于初始化ProcessLifecycleOwner和LifecycleDispatcher。

ContentProvider的onCreate()方法执行时间比Application的onCreate()执行时间还要早,而且肯定会执行。所以在ContentProvider的onCreate()方法里面初始化这是是没问题的。

我们看到还调用了LifecycleDispatcher的初始化的方法

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

@SuppressWarnings("WeakerAccess")
@VisibleForTesting
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() {
}
}

可以看到这里面也注册了registerActivityLifecycleCallbacks来监听生命周期,并在其onActivityCreated方法中创建了一个ReportFragment,哈哈还是使用ReportFragment。ReportFragment的injectIfNeededIn方法只会创建一个ReportFragment。所以即使我们在ComponentActivity中的onCreate方法中重复调用也只有一个实例。

OK到这里就看完了总结一下:

应用程序创建的时候,会初始化一个空的Fragment,虽然这个Fragment没有布局文件,但是它有一个完整的生命周期,而且生命周期跟它所在的这个Activity同步,所以我们就可以在这个Fragment的生命周期中来管理观察者的生命周期,通过addObserver方法,可以把一个我们自定义的观察者注册到Activiy中的一个集合中,当生命周期变化的时候,循环遍历集合,调用观察者相关的状态方法。


一般情况下lifecycle结合着ViewModel和LiveData一块使用。

Lifecycle的最佳实践

  • 保持UI控制器(activities and fragments)尽可能的精简,他们中不应该有请求数据的代码,这部分的代码我们最好交给 ViewModel去做,然后通过LiveData来更新视图。
  • 尝试编写数据驱动的UI,当数据改变的时候,UI控制器负责更改视图,或者把用户的操作传递给ViewModel
  • 可以使用Data Binding来让activities and fragments中的代码更少更简洁。
  • 如果UI界面非常复杂,可以尝试写一个presenter类来处理UI逻辑,这样可以使UI组件更容易测试。
  • 避免在ViewModel中引用View或者Activity的上下文,如果ViewModel执行时间过长,会导致View和Activity无法被回收。

Lifecycle的用例

  • 比如位置更新,在程序可见的时候,使用细粒度的位置更新,在程序后台运行时使用粗粒度的位置更新
  • 比如视频的缓冲,我们可以在activity销毁的时候,取消视频的缓冲
  • 启动和停止网络连接,在应用进入后台的时候,断开网络连接
  • 暂停和恢复动画,后台时停止动画,回到前台时在启动动画

コメント

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×