当前位置:网站首页>LeakCanary如何监听Service、Root View销毁时机?
LeakCanary如何监听Service、Root View销毁时机?
2022-08-01 10:15:00 【大鱼Ss】
本篇文章讲解LeakCanary如何监听Service、Root View销毁时机并添加到泄漏监听中的。
监听Service
销毁时机
我先说下大体的思路:
- 首先我们反射
ActivityThread
中属性名为mH
的Handler对象,这个对象大家都是很熟悉,AMS通过应用侧的ApplicationThread
发送调度通知,然后ApplicationThread将调度操作封装成Meesage
并通过这个名为mH的Handler发送出去,然后最终Message被执行,里面调度Acitivity、Service生命周期的操作也自然会被执行了;
- 然后我们反射给mH的属性
mCallback
赋值,这个属性对象在处理Message的时机是优先于Handler的handleMessage()
方法的,所以我们在这个mCallback是可以监听到Service生命周期调度的。
通过以上方式我们监听到Message
的what==116
时,就代表Service
将执行onDestroy()
生命周期,并将这个Service弱引用保存起来;
- 问题来了,Service的
onDestory()
什么时候执行完毕呢,这个时候我们就要从源码中寻找解决答案了。看下ActivityThread源码,最终会在handleStopService()
执行Service的onDestroy()方法:
可以看到,Service的onDestroy()
执行完毕后,就会调用IActivityManager
这个Binder
对象的方法serviceDoneExecuting()
通知AMS
。看到这里,是不是明白了怎么做。
- 我们可以通过反射动态代理掉应用侧的
IActivityManager
这个Binder对象,并重写其serviceDoneExecuting()
方法完成Service的onDestroy()执行完毕的监听。LeakCanary
中的源码就是这么做的:
首先动态代理创建一个实现了
IActivityManager
接口的对象,这个代理对象里面就会判断当前的方法为serviceDoneExecuting
时,代表当前的Service的onDestory()生命周期已经执行完毕,可以对当前Service添加内存泄漏监听了然后将当前ActivityManager对象中原有的IActivityManager这个
binder
对象替换成我们上面动态代理创建的IActivityManager
对象
- 通过以上方式,我们就实现了Service销毁时机的监听,并添加到内存泄漏的监听中。
监听Root View
销毁时机
这里监听Root View之一就是监听Dialog的根View是否发生了内存泄漏。看下LeakCanary
核心代码是如何处理的:
很熟悉的代码,就是拿到Dialog的根View,然后调用addOnAttchStateChangeListener添加监听,并在监听实现类中重写onViewDetachedFromWindow()
方法,当根View不可见的时候,就会触发该方法的执行。
至于LeakCanary
是怎么统一拿到业务层的Dialog
的根View布局的,笔者看了源码也不是很清楚怎么实现的,实现的代码如下,底层的原理就不懂了:
不过上面这种监听Dialog
的根View内存泄漏的方式有一个非常严重的问题:
大家在写代码的过程中可能会有一个习惯,在某个类中创建一个全局的成员变量持有这个Dialog,这样方便在全局调用其
show()
或者dismiss()
方法。
这样就会导致
Dialog
执行dismiss()
方法关闭弹窗时,Dialog被类的全局变量持有,而Dialog又会持有其根View,所以根View不会被回收销毁的。而这个时候根View已经从屏幕上消息不可见,就会回调onViewDetachedFromWindow()
方法,将根View添加到LeakCanary
的销毁监听中,这样就会百分之百导致内存泄漏。
上面这种情况下,本身业务类中的某个全局成员属性持有Dialog的行为是很正常的,所以就只能LeakCanary
去兼容处理了:
可以看到LeakCanary
能不能检测Dialog的Root View(根View)
是有开关可以控制的,如果我们项目中存在业务类全局持有Dialog的行为,就可以在xml中将leak_canary_watcher_watch_dismissed_dialogs
设置为false
即可,这样LeakCanary就不会检测Dialog的Root View销毁了。
作者:长安皈故里
链接:https://juejin.cn/post/7114683266170372104
更多Android相关知识、学习笔记、视频资料详情可扫描下方二维码领取!!
边栏推荐
- 【云驻共创】分布式技术之华为云全域调度技术与实践
- CTO strongly banning the use of the Calendar, that in what?
- Basic configuration commands of cisco switches (what is the save command of Huawei switches)
- SQL Server database schema and objects related knowledge notes
- 7. SAP ABAP OData 服务如何支持 $orderby (排序)操作
- redis
- rpm and yum
- Explain / Desc execution plan analysis
- Mini Program Graduation Works WeChat Food Recipes Mini Program Graduation Design Finished Products (2) Mini Program Functions
- [Software Architecture Mode] The difference between MVVM mode and MVC mode
猜你喜欢
可视化——Superset安装与部署
Comprehensive experiment BGP
报告:想学AI的学生数量已涨200%,老师都不够用了
周鸿祎称微软抄袭 360 安全模式后发文否认;英特尔CEO基辛格回应市值被AMD超越:股价下跌是咎由自取|极客头条
Golang内存分析工具gctrace和pprof实战
How to Steal $100 Million from the Perfect Smart Contract
SAP ABAP OData 服务如何支持 $orderby (排序)操作试读版
C语言小游戏——扫雷
AI篮球裁判火了,走步算得特别准,就问哈登慌不慌
【软件架构模式】MVVM模式和MVC模式区别
随机推荐
What are the common API security flaws?
Glassmorphism design style
Android Security and Protection Policy
mysql在cmd的登录及数据库与表的基本操作
【软件架构模式】MVVM模式和MVC模式区别
基于ModelArts的物体检测YOLOv3实践【玩转华为云】
什么是步进电机?40张图带你了解!
Batch大小不一定是2的n次幂!ML资深学者最新结论
C语言程序设计50例(三)(经典收藏)
50.【动态二维数组的运用】
What's up with VS "Cannot find or open PDB file"?How to solve
Naive Bayes--Study Notes--Basic Principles and Code Implementation
C#/VB.NET convert PPT or PPTX to image
xss-labs靶场挑战
WPF 截图控件之绘制箭头(五)「仿微信」
ModelArts-based object detection YOLOv3 practice [play with HUAWEI CLOUD]
Meeting OA (Upcoming Meetings & All Meetings)
玻璃拟态(Glassmorphism)设计风格
深度学习 | MATLAB实现一维卷积神经网络convolution1dLayer参数设定
微信公众号授权登录后报redirect_uri参数错误的问题