【背上Jetpack】Jetpack 主要组件的依赖及传递关系
【背上Jetpack】AdroidX下使用Activity和Fragment的变化
【背上Jetpack之Fragment】你真的会用Fragment吗?Fragment常见问题以及androidx下Fragment的使用新姿势
【背上Jetpack之Fragment】从源码角度看 Fragment 生命周期 AndroidX Fragment1.2.2源码分析
【背上Jetpack之OnBackPressedDispatcher】Fragment 返回栈预备篇
【背上Jetpack之Fragment】从源码的角度看Fragment 返回栈 附多返回栈demo
【背上Jetpack】绝不丢失的状态 androidx SaveState ViewModel-SaveState 分析
【背上Jetpack之ViewModel】即使您不使用MVVM也要了解ViewModel ——ViewModel 的职能边界
Android 中有一个比较重要的概念:「生命周期」。刚毕业去面试,总会被问到「四大组件的生命周期」这类的问题。17年的 IO 大会上,Google 推出了 Lifecycle-Aware Components(生命周期感知组件),帮助开发者组织更好,更轻量,易于维护的代码
本文介绍 Lifecycle
的职责以及简单分析 lifecycle 如何感知 activity 和 fragment ,帮助您对 Lifecycle
有一个感性的认识
鲁迅曾说过:万物基于 Lifecycle
哦不对
Android 中的视图控制器就有这么多生命周期的情况,所以处理好生命周期十分重要,否则会导致内存泄漏甚至是程序崩溃。这里引用 官方文档 的例子
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 连接系统的定位服务
}
void stop() {
// 与系统的定位服务断开连接
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
//管理其他需要响应 activity 生命周期的组件
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
//管理其他需要响应 activity 生命周期的组件
}
}
此示例看起来不错,在实际的应用程序中,您仍然会响应生命周期的当前状态而进行过多的调用来管理 UI 和其他组件。 管理多个组件会在生命周期方法中放置大量代码,例如 onStart() 和 onStop(),这使它们难以维护
而且,不能保证组件在 activity 或 fragment 停止之前就已启动。 如果我们需要执行长时间运行的操作(例如onStart() 中的某些配置检查),则可能会导致争用情况,其中onStop() 方法在 onStart() 之前完成,从而使组件的生存期超过了所需的生存期。
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, location -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
// 如果在 activity 停止后调用此回调怎么办?
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
如果有所有的组件,都能感知外部的生命周期,能在相应的时机释放资源,并且在错过生命周期时能及时叫停异步的任务就好了,
我们不妨先思考一下,如果实现这样的想法,应该如何做
首先我们先来整理一下我们的需求
针对需求1,可以用观察者模式,内部组件能够在外部生命周期变化时做出相应
针对需求2,可以将依赖组件的代码移出生命周期方法内,然后移入组件本身,这样只需修改组件内部逻辑即可
针对需求3,可以在合适的时机移除观察者
关于开发者模式,我第一次比较详细的了解是在 扔物线 的 给 Android 开发者的 RxJava 详解。
观察者模式面向的需求是:A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感,需要在 B 变化的一瞬间做出反应。举个例子,新闻里喜闻乐见的警察抓小偷,警察需要在小偷伸手作案的时候实施抓捕。在这个例子里,警察是观察者,小偷是被观察者,警察需要时刻盯着小偷的一举一动,才能保证不会漏过任何瞬间。程序的观察者模式和这种真正的『观察』略有不同,观察者不需要时刻盯着被观察者(例如 A 不需要每过 2ms 就检查一次 B 的状态),而是采用注册(Register)或者称为订阅**(Subscribe)**的方式,告诉被观察者:我需要你的某某状态,你要在它变化的时候通知我。 Android 开发中一个比较典型的例子是点击监听器
OnClickListener
。对设置OnClickListener
来说,View
是被观察者,OnClickListener
是观察者,二者通过setOnClickListener()
方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的OnClickListener
。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。当然,这也得益于我们可以随意定制自己程序中的观察者和被观察者,而警察叔叔明显无法要求小偷『你在作案的时候务必通知我』。
OnClickListener 的模式大致如下图:
上述描述及图片均来自 给 Android 开发者的 RxJava 详解
因此在生命周期组件的生命周期发生变化时告诉观察者,内部组件即可感知外部的生命周期
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());
这是 Lifecycle 的结构,抽象类,其内部有两个枚举,分别代表着「事件」和「状态」,此外还有三个方法,添加/移除观察者,获取当前状态
注意,这里 State 中的枚举顺序是有意义的,后文详细介绍
其实现类为 LifecycleRegistry ,可以处理多个观察者
其内部持有当前的状态 mState ,LifecycleOwner 以及观察者的自定义列表,同时重写了父类的添加/删除观察者的方法
LifecycleOwner ,具有 Android 的生命周期,定制组件可以使用这些事件来处理生命周期更改,而无需在 Activity 或 Fragment 中实现任何代码
LifecycleObserver ,将一个类标记为 LifecycleObserver
。 它没有任何方法,而是依赖于 OnLifecycleEvent 注解的方法
LifecycleEventObserver ,可以接收任何生命周期更改并将其分派给接收方。
如果一个类实现此接口并同时使用 OnLifecycleEvent,则注解将被忽略
DefaultLifecycleObserver ,用于监听 LifecycleOwner 状态更改的回调接口。
如果一个类同时实现了此接口和 LifecycleEventObserver,则将首先调用DefaultLifecycleObserver
的方法,然后再调用LifecycleEventObserver.onStateChanged(LifecycleOwner,Lifecycle.Event)
注意:使用 DefaultLifecycleObserver 需引入
implementation “androidx.lifecycle:lifecycle-common-java8:$lifecycle_version”
首先我们还是来看 androidx.activity.ComponentActivity ,这个类我们这个系列的文章里提到多次,第一次提及是在 【背上Jetpack】绝不丢失的状态 androidx SaveState ViewModel-SaveState 分析 ,感兴趣的小伙伴可以看看。
其实现的接口大多数我们都已经探讨过了,今天我们来看看 LifecycleOwner
ActivityResultCaller 为 activity 1.2.0-alpha02 推出的,旨在统一 onActivityResult ,这里暂时不讨论它
既然实现了 LifecycleOwner
接口,必定重写 getLifecycle() 方法
// androidx.activity.ComponentActivity.java
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
其返回的 Lifecycle
为 实现类 LifecycleRegistry
的实例
而 activity 操作生命周期是通过 ReportFragment
处理的
// androidx.activity.ComponentActivity.java
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
//...
}
// ReportFragment
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// api 29 及以上 直接注册正确的生命周期回调
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
// ReportFragment.java
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
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);
}
}
}
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
dispatch(getActivity(), event);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
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);
}
// LifecycleCallbacks
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
dispatch(activity, Lifecycle.Event.ON_CREATE);
}
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_START);
}
@Override
public void onActivityPostResumed(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_RESUME);
}
@Override
public void onActivityPrePaused(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_PAUSE);
}
@Override
public void onActivityPreStopped(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_STOP);
}
@Override
public void onActivityPreDestroyed(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_DESTROY);
}
//...
}
在 activity 的 onCreate 方法中,调用了 ReportFragment
中的静态方法 injectIfNeededIn()
。而其内部,如果 api 29 及以上的设备上直接注册正确的生命周期回调,低版本通过启动 ReportFragment ,借助 fragment 各个生命周期来处理生命周期回调
在 fragment 内部,每个生命周期节点调用 handleLifecycleEvent
方法
// Fragment.java
public Fragment() {
initLifecycle();
}
private void initLifecycle() {
mLifecycleRegistry = new LifecycleRegistry(this);
}
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
void performCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState);
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() {
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();
}
Lifecycle.State
中有一个 isAtLeast
方法,用于判断当前状态是否不小于传入的状态
// Lifecycle.State
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
枚举的 compareTo 方法其实是比较的枚举声明的顺序
而 State 的顺序为 DESTROYED -> INITIALIZED -> CREATED -> STARTED -> RESUMED
如果传入的 state 为 STARTED,则当前状态为 STARTED 或 RESUMED 时返回 true ,否则返回 false
LiveData 篇会用到这个知识点
我是 Fly_with24