从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生命周期的监听。

相关推荐
ii_best5 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk5 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭10 小时前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin
aqi0010 小时前
FFmpeg开发笔记(七十七)Android的开源音视频剪辑框架RxFFmpeg
android·ffmpeg·音视频·流媒体
androidwork12 小时前
深入解析内存抖动:定位与修复实战(Kotlin版)
android·kotlin
梦天201512 小时前
android核心技术摘要
android
szhangbiao14 小时前
“开发板”类APP如果做屏幕适配
android
高林雨露15 小时前
RecyclerView中跳转到最后一条item并确保它在可视区域内显示
android
移动开发者1号17 小时前
ReLinker优化So库加载指南
android·kotlin
刘龙超17 小时前
如何应对 Android 面试官 -> 玩转 JetPack LiveData
android jetpack