Headless Fragment 监听 Activity 或 Fragment 生命周期

监听 Activity 或者 Fragment 的生命周期对于很多开发者来说是小菜一碟,重载onResumeonPause等方法就行了,的确很多时候这种方法就可以了。但是这种方法是侵入式的,需要修改 Activity 或者 Fragment 的实现,但有时我们不能修改它们的实现,例如第三方 SDK 需要监听宿主页面的生命周期,这时需要非侵入式的实现方法。

对于 Activity 来说,可以注册 Application.ActivityLifecycleCallbacks 回调来监听其生命周期。但是对 Fragment 又应该怎么办呢?

Headless Fragment 监听生命周期

Headless Fragment 是没有布局不可见的 Fragment。Fragment 是与相关的 FragmentManager 的组件的生命周期相关联的,例如 Activity 的 onPause 会引起其中 Fragment 的 onPause。因为 Headless Fragment 是不可见的,所以它可以用来监听 Activity 和 Fragment 的生命周期。

1
2
3
4
5
6
7
8
9
10
11
LifecycleFragment fragment = new LifecycleFragment();
// 监听 Activity 生命周期
FragmentTransaction transaction = targetActivity.getFragmentManager().beginTransaction();
transaction.add(fragment, TAG);
transaction.commit();
// 监听 Fragment 生命周期
FragmentTransaction transaction = targetFragment.getChildFragmentManager().beginTransaction();
transaction.add(fragment, TAG);
transaction.commit();

这时只需要重载 LifecycleFragment 中的方法就可以监听 target 的生命周期了。 如果 Activity 或者 Fragment 在屏幕方向变化时不会重新创建,LifecycleFragment 添加setRetainInstance(true)与之对应。

nekocode 的 RxLifecycle 就是使用这个 hack 技巧来实现非侵入式的 RxLifecycle。

Headless Fragment 的其他用途

替代 BaseActivity

BaseActivity 是对 activitys 的共有逻辑的抽象,减少我们 copy and paste 的工作,但是在逻辑越来越多时,BaseActivity 的一些逻辑对一些 Activity 来说是不需要的,这时需要用标记位来禁用一些功能,但是这种写法会让代码很难维护。

使用 Headless Fragment 的话,可以把 A 相关的逻辑封装到 AFragment,把 B 相关的逻辑封装到 BFragment, Activity 使用时再添加需要的 Fragment 就可以了

Service 的另一种选择

Headless Fragment 也可以用来处理与生命周期有关的异步任务

监听网络变化或请求运行时权限

Use headless Fragment for Android M run-time permissions and to check network connectivity