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

相关推荐
斗锋在干嘛6 小时前
Android里面内存优化
android
jiet_h7 小时前
深入解析Kapt —— Kotlin Annotation Processing Tool 技术博客
android·开发语言·kotlin
alexhilton8 小时前
实战:探索Jetpack Compose中的SearchBar
android·kotlin·android jetpack
uhakadotcom9 小时前
EventBus:简化组件间通信的利器
android·java·github
笑鸿的学习笔记10 小时前
ROS2笔记之服务通信和基于参数的服务通信区别
android·笔记·microsoft
89315196011 小时前
Android开发融云获取多个会话的总未读数
android·android开发·android教程·融云获取多个会话的总未读数·融云未读数
zjw_swun11 小时前
实现了一个uiautomator玩玩
android
pengyu11 小时前
系统化掌握Dart网络编程之Dio(二):责任链模式篇
android·flutter·dart
水w11 小时前
【Android Studio】如何卸载干净(详细步骤)
android·开发语言·android studio·activity
亦是远方11 小时前
2025华为软件精英挑战赛2600w思路分享
android·java·华为