从LeakCanary看Fragment生命周期监控

前文中我们已经了解到LeakCanary中Service生命销毁的监听方式,那么Fragment的生命周期监听又是怎么实现的呢?

Activity生命周期监听,在Application里面有ActivityLifecycleCallbacks,那么Fragment是否相似呢?我们的第一想法自然是查找系统中是否有FragmentLifecycleCallback之类的回调,在Android官方文档中查找FragmentLifecycleCallback,结果如下图:

可以看到在android.app,android.fragment.app以及android.support.v4.app包下均有FragmentLifecycleCallbacks类,那么该类的作用是否与我们期望一致,能否用于监听Fragment生命周期变化呢?我们来看下该类的说明以及相关接口:

Callback interface for listening to fragment state changes that happen within a given FragmentManager.

从该类说明可以看出其是用于监听给定FragmentManager中fragment状态变化的回调接口,也就意味着我们可以通过该接口来监听Fragment生命周期变化。

那么如何注册该接口作为Fragment生命周期监听器呢?其实前文截图中也有,registerFragmentLifecycleCallbacks,通过该方法我们就可以监听Fragment生命周期变化,该方法声明如下:

也就是说我们可以通过FragmentManager来注册FragmentLifecycleCallbacks作为监听器。

大家都知道FragmentManager需要通过Activity来获得,这也就意味着我们要获得Activity对象,问题进一步转化为全局监听Activity的生命周期变化,文章开头已经提到了,我们可以通过Application中的ActivityLifecycleCallbacks来监听Activity生命周期变化,那么Fragment生命周期监控的实现流程已经很清晰了:

  1. 监听Activity生命周期变化
  2. 在Activity创建时,获取其关联的FragmentManager对象
  3. 使用registerFragmentLifecycleCallbacks向FragmentManager注册监听器

监听Activity生命周期变化

监听Activity生命周期很简单,我们直接上代码:

less 复制代码
 application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
     @Override
     public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
         // activity创建,获取其关联的FragmentManager
     }
 ​
     @Override
     public void onActivityStarted(@NonNull Activity activity) {
 ​
     }
 ​
     @Override
     public void onActivityResumed(@NonNull Activity activity) {
 ​
     }
 ​
     @Override
     public void onActivityPaused(@NonNull Activity activity) {
 ​
     }
 ​
     @Override
     public void onActivityStopped(@NonNull Activity activity) {
 ​
     }
 ​
     @Override
     public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
 ​
     }
 ​
     @Override
     public void onActivityDestroyed(@NonNull Activity activity) {
 ​
     }
 });

获取关联的FragmentManager对象

从Activity中获取关联的FragmentManager对象时,需要注意的是,我们前文提到在android.app,android.fragment.app以及android.support.v4.app包下均存在FragmentManager,我们需要根据项目中是否使用到相关库来确定以那种方式获取FragmentManager对象。

判断项目中是否使用到相关库

对于Activity而言,我们并不能显示获取或指定Activity所使用的Fragment以及相关类,那么如何判断呢?简单来讲,我们是否可以认为,当代码中存在该包名下的文件时,则Activity有可能用到这个包名下的Fragment,此时我们就需要针对这类Fragment添加监听器。

怎么判断代码中是否存在该包名下的文件呢?通过类加载器,我们通过类加载器加载该包名下文件,如果成功加载,则说明项目中使用到了,如果加载异常,则说明项目中不存在,不需关注。类加载包含函数如下:

typescript 复制代码
 private boolean isClassAvailable(String classname) {
     try {
         Class.forName(classname);
         return true;
     }catch (Throwable e) {
         return false;
     }
 }

获取FragmentManager

scss 复制代码
 if ((isClassAvailable("androidx.fragment.app.Fragment") || isClassAvailable("android.support.v4.app.Fragment")) && activity instanceof FragmentActivity) {
     FragmentManager fragmentManager = ((FragmentActivity)activity).getSupportFragmentManager();
 }
 ​
 // Android O开始才有registerFragmentLifecycleCallbacks方法
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
     android.app.FragmentManager fragmentManager = activity.getFragmentManager();
 }

注册监听器

注册监听器的代码实现比较简单,直接上代码:

typescript 复制代码
 fragmentManager.registerFragmentLifecycleCallbacks(new android.app.FragmentManager.FragmentLifecycleCallbacks() {
     @Override
     public void onFragmentDestroyed(android.app.FragmentManager fm, android.app.Fragment f) {
         super.onFragmentDestroyed(fm, f);
     }
 },true);

至此,我们就完成了Fragment生命周期的监听。

相关推荐
消失的旧时光-194323 分钟前
kotlin的密封类
android·开发语言·kotlin
服装学院的IT男2 小时前
【Android 13源码分析】WindowContainer窗口层级-4-Layer树
android
CCTV果冻爽3 小时前
Android 源码集成可卸载 APP
android
码农明明3 小时前
Android源码分析:从源头分析View事件的传递
android·操作系统·源码阅读
秋月霜风4 小时前
mariadb主从配置步骤
android·adb·mariadb
Python私教5 小时前
Python ORM 框架 SQLModel 快速入门教程
android·java·python
编程乐学6 小时前
基于Android Studio 蜜雪冰城(奶茶饮品点餐)—原创
android·gitee·android studio·大作业·安卓课设·奶茶点餐
problc7 小时前
Android中的引用类型:Weak Reference, Soft Reference, Phantom Reference 和 WeakHashMap
android
IH_LZH7 小时前
Broadcast:Android中实现组件及进程间通信
android·java·android studio·broadcast
去看全世界的云7 小时前
【Android】Handler用法及原理解析
android·java