上面文章讲了 Android Support Library 26.1.0 开始,引入Lifecycles。官方正式完善了 Activity、Fragment 生命周期监控这方面的代码。
在这之前我有看到这么两种方案。
第一种是 Glide 使用的方案。
以上是Glide 的简单用法是这样的。
1、如何实现绑定生命周期
public class Glide implements ComponentCallbacks2 {
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
Glide.with 方法可以传入不同的参数,上面这4个方法都会先通过 getRetriever 方法获取到 RequestManagerRetriever。
RequestManagerRetriever 是一个 RequestManager 的容器。用来新建&缓存 RequestManager 实体。
这里拿参数是 Activity 的方法来举例。
getRetriever(activity).get(activity); 前半句 getRetriever(activity) 是获取 Glide 类的属性 requestManagerRetriever。
后半句是获取一个 RequestManager。展开里面的详细代码如下:
RequestManagerRetriever.java
——————————————————————————————
public class RequestManagerRetriever implements Handler.Callback {
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
RequestManagerFragment.java
——————————————————————————————
public class RequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
由于新建一个 RequestManager 需要一个「生命周期实体 Lifecycle」的传参。
什么东西可以获取到生命周期呢,Activity里已经无法插入代码,还有其他办法吗?
如果了解我上篇文章《Android LiveData我的理解》,可以猜到 Glide 也是要利用了为 Activity 里面添加无UI的Fragment这招了。事实上这招应该 Glide 先发现的。
Glide 为这套流程编写了一个 Fragment 的子类 RequestManagerFragment,创建 RequestManagerFragment 的构造方法会创建一个 ActivityFragmentLifecycle。最终实现 RequestManager 和 这个 RequestManagerFragment 里面的 ActivityFragmentLifecycle 绑定。 RequestManager 就获得了一个「生命周期实体 Lifecycle」的传参了。
上面这段代码就是这段逻辑的实现,其中还有一个细节是 RequestManagerFragment 会尝试从缓存中获取。
RequestManager 是利用工厂模式, factory.build 方法创建的,其中传入最重要的参数 RequestManagerFragment 里面的 lifecycle。它的构造方法如下:
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
final Lifecycle lifecycle;
private final Runnable addSelfToLifecycle = new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
// If we're the application level request manager, we may be created on a background thread.
// In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
// issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
// This should be entirely safe.
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
在 RequestManager 的构造方法中,会执行 lifecycle.addListener(this); 把当前 RequestManager 添加到 lifecycle 的观察者列表里。
2、如何接受生命周期事件
在 RequestManagerFragment 中,重写了 onStart、onStop、onDestroy 方法。
RequestManagerFragment.java
——————————————————————————————
public class RequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
ActivityFragmentLifecycle.java
——————————————————————————————
class ActivityFragmentLifecycle implements Lifecycle {
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
RequestManager.java
——————————————————————————————
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public synchronized void onDestroy() {
targetTracker.onDestroy();
for (Target<?> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
mainHandler.removeCallbacks(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
这3个方法里会调用到 lifecycle 的方法,lifecycle会遍历自身的 lifecycleListeners,执行对应方法。因为 RequestManager 刚才添加监听时候传入了自己,也实现了 LifecycleListener 接口,所以最终回调到这里的 onStart、onStop、onDestroy 方法。比如 onDestroy 就会去取消加载图片任务,释放相应资源,把自己从生命周期监听集合中移除。
ps:RequestManager、ActivityFragmentLifecycle 和 RequestManagerFragment 这3者是1对1对1的关系。一个 RequestManager 管理着这个页面(Activity/Fragment)下的所有图片加载任务。当这个页面(Activity/Fragment)销毁了,对应的 RequestManagerFragment 也销毁了,对应的 RequestManager 的所有任务也应该取消掉+资源释放掉。
第二种是 MVPArms 使用的方案。
MVPArms 是一个 Android MVP 快速集成框架,里面用到 RxLifecycle 库。
RxLifecycle 作用是可以根据生命周期发送的事件,自动释放(dispose) Rxjava2 的订阅。
免除你手写 dispose 代码,可以防止内存泄露的情况发生。
1、 Activity & Fragment 全局性的生命周期回调
Application.java
——————————————————————————————
public class Application extends ContextWrapper implements ComponentCallbacks2 {
public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.add(callback);
}
}
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
FragmentManager.java
——————————————————————————————
public abstract class FragmentManager {
public abstract void registerFragmentLifecycleCallbacks(@NonNull FragmentManager.FragmentLifecycleCallbacks var1, boolean var2);
public abstract static class FragmentLifecycleCallbacks {
public FragmentLifecycleCallbacks() {}
public void onFragmentPreAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {}
public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {}
public void onFragmentPreCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {}
public void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {}
public void onFragmentActivityCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {}
public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull View v, @Nullable Bundle savedInstanceState) {}
public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentSaveInstanceState(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Bundle outState) {}
public void onFragmentViewDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {}
}
FragmentManagerImpl.java
——————————————————————————————
final class FragmentManagerImpl extends FragmentManager implements Factory2 {
public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb, boolean recursive) {
this.mLifecycleCallbacks.add(new FragmentManagerImpl.FragmentLifecycleCallbacksHolder(cb, recursive));
}
在 Application 里使用 registerActivityLifecycleCallbacks 注册 Actiivity 的生命周期回调估计大家都知道了。Fragment 也有相应的注册生命周期回调的方法,是在 FragmentManager 里使用 registerFragmentLifecycleCallbacks。
提示到这步应该很好猜到下面怎么实现了。就是在这么 Activity/Fragment 的 callback 方法里插入发送生命周期事件的代码。
2、Activity 的生命周期注册
需要先讲解一下 RxLifecycle 的原理。大概可以理解为,RxJava 像是上游发送数据给下游,正常流程「下游Observer」 在 Activity/Fragment 销毁后应该跟着销毁+释放资源。
RxLifecycle 的原理是让 「下游Observer」可以接收另一个上游事件,在这里是生命周期事件,比如设定接收到 onDestroy 事件就把这个 RxJava 流销毁+释放资源。
Lifecycleable.java
——————————————————————————————
public interface Lifecycleable<E> {
@NonNull
Subject<E> provideLifecycleSubject();
}
ActivityLifecycleable.java
——————————————————————————————
public interface ActivityLifecycleable extends Lifecycleable<ActivityEvent> {
}
FragmentLifecycleable.java
——————————————————————————————
public interface FragmentLifecycleable extends Lifecycleable<FragmentEvent> {
}
BaseActivity.java
——————————————————————————————
public abstract class BaseActivity<P extends IPresenter> extends AppCompatActivity implements IActivity, ActivityLifecycleable {
private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();
@NonNull
@Override
public final Subject<ActivityEvent> provideLifecycleSubject() {
return mLifecycleSubject;
}
BaseFragment.java
——————————————————————————————
public abstract class BaseFragment<P extends IPresenter> extends Fragment implements IFragment, FragmentLifecycleable {
private final BehaviorSubject<FragmentEvent> mLifecycleSubject = BehaviorSubject.create();
@NonNull
@Override
public final Subject<FragmentEvent> provideLifecycleSubject() {
return mLifecycleSubject;
}
MVPArms 中在 BaseActivity 和 BaseFragment 就实现了一个 Lifecycleable 接口,提供出来了一个获取 Subject 的方法。这里Subject 可以暂时理解为一个上游事件发射器。
下面来看看实现了 Application.ActivityLifecycleCallbacks 的子类,这个子类会在 application 中调用 register 方法进行注册。
ActivityLifecycleForRxLifecycle.java
——————————————————————————————
public class ActivityLifecycleForRxLifecycle implements Application.ActivityLifecycleCallbacks {
@Inject
Lazy<FragmentLifecycleForRxLifecycle> mFragmentLifecycle;
@Inject
public ActivityLifecycleForRxLifecycle() {
}
/**
* 通过桥梁对象 {@code BehaviorSubject<ActivityEvent> mLifecycleSubject}
* 在每个 Activity 的生命周期中发出对应的生命周期事件
*/
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity instanceof ActivityLifecycleable) {
obtainSubject(activity).onNext(ActivityEvent.CREATE);
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycle.get(), true);
}
}
}
@Override
public void onActivityStarted(Activity activity) {
if (activity instanceof ActivityLifecycleable) {
obtainSubject(activity).onNext(ActivityEvent.START);
}
}
@Override
public void onActivityResumed(Activity activity) {
if (activity instanceof ActivityLifecycleable) {
obtainSubject(activity).onNext(ActivityEvent.RESUME);
}
}
@Override
public void onActivityPaused(Activity activity) {
if (activity instanceof ActivityLifecycleable) {
obtainSubject(activity).onNext(ActivityEvent.PAUSE);
}
}
@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof ActivityLifecycleable) {
obtainSubject(activity).onNext(ActivityEvent.STOP);
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
if (activity instanceof ActivityLifecycleable) {
obtainSubject(activity).onNext(ActivityEvent.DESTROY);
}
}
/**
* 从 {@link com.jess.arms.base.BaseActivity} 中获得桥梁对象 {@code BehaviorSubject<ActivityEvent> mLifecycleSubject}
*
* @see <a href="https://mcxiaoke.gitbooks.io/rxdocs/content/Subject.html">BehaviorSubject 官方中文文档</a>
*/
private Subject<ActivityEvent> obtainSubject(Activity activity) {
return ((ActivityLifecycleable) activity).provideLifecycleSubject();
}
}
各个生命周期的回调方法会把 activity 实体当做参数传过来,所以根据这个 activity 判断+强转成 ActivityLifecycleable,然后获取到 生命周期的上游事件发射器 Subject,发送一个生命周期事件出去。
注意在 onActivityCreated 方法中,判断 instanceof FragmentActivity,然后会注册 Fragment 生命周期的回调。
因为涉及到 dagger2 的使用,在这里不是重点所以省略了。mFragmentLifecycle.get() 在这里返回的是一个 FragmentLifecycleForRxLifecycle 实例,下面是 FragmentManager.FragmentLifecycleCallbacks 的子类实现。
@Singleton
public class FragmentLifecycleForRxLifecycle extends FragmentManager.FragmentLifecycleCallbacks {
@Inject
public FragmentLifecycleForRxLifecycle() {
}
@Override
public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.ATTACH);
}
}
@Override
public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.CREATE);
}
}
@Override
public void onFragmentViewCreated(FragmentManager fm, Fragment f, View v, Bundle savedInstanceState) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.CREATE_VIEW);
}
}
@Override
public void onFragmentStarted(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.START);
}
}
@Override
public void onFragmentResumed(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.RESUME);
}
}
@Override
public void onFragmentPaused(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.PAUSE);
}
}
@Override
public void onFragmentStopped(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.STOP);
}
}
@Override
public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.DESTROY_VIEW);
}
}
@Override
public void onFragmentDestroyed(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.DESTROY);
}
}
@Override
public void onFragmentDetached(FragmentManager fm, Fragment f) {
if (f instanceof FragmentLifecycleable) {
obtainSubject(f).onNext(FragmentEvent.DETACH);
}
}
private Subject<FragmentEvent> obtainSubject(Fragment fragment) {
return ((FragmentLifecycleable) fragment).provideLifecycleSubject();
}
}
跟 activity 类型,这里也是根据方法的参数 fragment 判断+强转成 FragmentLifecycleable,然后获取到 生命周期的上游事件发射器 Subject,发送一个生命周期事件出去。
最终使用时候
UserPresenter.java 业务类中使用
——————————————————————————————
Observable
.just("yao")
.compose(RxLifecycleUtils.bindToLifecycle(mRootView))//这个mRootView实际是一个activity/fragment
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
}
});
RxLifecycleUtils.java
——————————————————————————————
public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull IView view) {
Preconditions.checkNotNull(view, "view == null");
if (view instanceof Lifecycleable) {
return bindToLifecycle((Lifecycleable) view);
} else {
throw new IllegalArgumentException("view isn't Lifecycleable");
}
}
public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull Lifecycleable lifecycleable) {
Preconditions.checkNotNull(lifecycleable, "lifecycleable == null");
if (lifecycleable instanceof ActivityLifecycleable) {
return RxLifecycleAndroid.bindActivity(((ActivityLifecycleable) lifecycleable).provideLifecycleSubject());
} else if (lifecycleable instanceof FragmentLifecycleable) {
return RxLifecycleAndroid.bindFragment(((FragmentLifecycleable) lifecycleable).provideLifecycleSubject());
} else {
throw new IllegalArgumentException("Lifecycleable not match");
}
}
因为 MVPArms 涉及了很高 dagger2 和 Rxjava2 的用法,要深究的话就讲不完了。所以简略讲一下,这里大概的意思是,使用了 Rxjava2 的 compose 方法,传进入一个 activity/fragment 的实例,里面会把当前这个 Rxjava 序列和生命周期序列组成一个新的序列。这个新的序列收到某个生命周期事件,就会自我销毁。
以上是两者开源库的方案,终极方案还是得靠 Google 的 Lifecycle。
ps:上一篇博客写 LiveData,写到一半发现要讲清楚 LiveData 需要先讲清楚 Lifecycle。没办法就在头部插入了 Lifecycle 介绍的代码。所以就把上篇博客讲的 Lifecycle 部分再次在这粘贴一遍了。
!!! 官方 Lifecycle 方案 !!!
Lifecycle 可以理解为一个库或一堆类,加上在Activity、Fragment里面插入的一些逻辑代码,最终实现的生命周期可以通知到外界的体系。
像观察者模式一样。可以分为注册、反注册、发送事件和接受事件这4部分。
先来看发送部分。
发送部分(处于源码里面)
上面这个图以 android.support.v4.app.Fragment.java 为例,可以看到从8.1.0开始,在 performCreate、performStart、performResume、performPause、performStop 和 performDestroy 等方法都加上了发送生命周期 Event 事件。
Activity 发送生命周期 Event 会复杂一点,是在 android.support.v4.app.SupportActivity 里通过创建一个 ReportFragment,把在各个生命周期中发事件的代码逻辑挪进去 ReportFragment 里实现的。
这一招数让我想起了 Glide 对于图片生命周期的管理。Glide.with(Activity) 也是让 Activity 创建出一个 Fragment ,在 Fragment 的各个生命周期方法内插入回调函数后,执行代码来实现的。
SupportActivity.java(support库)
------------------------------
@Override
@SuppressWarnings("RestrictedApi")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ComponentActivity.java(androidx库)
------------------------------
@Override
@SuppressWarnings("RestrictedApi")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ReportFragment.java
------------------------------
@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);
}
}
}
Activity 和 Fragment 都会调用到 LifecycleRegistry.handleLifecycleEvent(event) 方法。
LifecycleRegistry 是在 ComponentActivity 和 Fragment 中声明并且直接new出来的成员变量。
同时它们还是实现了 LifecycleOwner 接口,里面的 getLifecycle() 就是返回这个 mLifecycleRegistry 用的。
SupportActivity.java(用于support库)
------------------------------
public class SupportActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
ComponentActivity.java(用于androidx库)
------------------------------
public class ComponentActivity extends Activity
implements LifecycleOwner, KeyEventDispatcher.Component {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
Fragment.java
------------------------------
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner {
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
LifecycleOwner.java
------------------------------
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
用了 LifecycleRegistry 来管理注册到Activity或Fragment来的所有观察者。包括添加、删除观察者,接受生命周期事件并分发到各个观察者中。
LifecycleRegistry 会维护一个 State 变量。同时这些观察者 ObserverWithState 也会有维护一份属于自己的声明周期状态 State。
这两份 State 的作用是,两者比较后,可以决定观察者列表「从前往后遍历」还是「从后往前遍历」。为什么要分「从前往后遍历」还是「从后往前遍历」我猜可能是一些观察者要遵循栈的后进先出原则吧,后注册的一些观察者组件需要先进行反注册操作。
下面这图是Lifecycles体系里面 State 和 Event 的关系。
LifecycleRegistry.handleLifecycleEvent(event) 之后接着是
LifecycleRegistry.sync() 方法,接着是
backwardPass() 或者 forwardPass(),代表从后往前遍历还是从前往后遍历。
在里面会遍历 LifecycleRegistry 的成员变量 mObserverMap,这个 Map 就是该 Activity/Fragment 生命周期的观察者。遍历 Map 后逐个调用 ObserverWithState.dispatchEvent(),最后执行 GenericLifecycleObserver.onStateChanged()。即逐个通知到观察者,当前 Activity/Fragment 处于哪个生命周期里了。
注册、反注册和接受通知(处于源码外面,需要开发者写)
说完发送生命周期通知事件后,就该讲在外面我们如何使用观察者监听通知了,包括注册、反注册和接受通知。
简单写法一般有这么两种,这是第一种,注解声明只接受 ON_RESUME 事件通知
这是第二种
注册后可以成功收到相应事件。看logcat日志,我把一个MainActivity打开又关闭后,输出了这些日志。
ps:GenericLifecycleObserver 下面报红了,因为这个类上面的注解说明了,这个类只应该在自己的library 里面使用。可以忽略这个警告。看 GenericLifecycleObserver 头像的注解,如下图
总结:
早于 google 推出 Lifecycle 方案时,开源库已经有了用 Activity/Fragment 生命周期监控的功能。谷歌在26.1.0算是推出了官方实现。Lifecycle 这一套还是很有用的,可以减少我们在各个生命周期回调中插入代码,更加的解耦。民间已经开始使用 Lifecycle 写一些比如 Handler 这种有销毁需求的功能了,减少我们在 onDestroy 释放资源的代码。可能等到 26.1.0+ 占据主流后,Glide 库会改用这套方案,各个开源库也会更多的使用到 Lifecycle 功能。