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

相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui