目录
- 废话
- 正题
- 搜索关键方法
- 初始化原理
- 上下文赋值流程
- 一些问题
0.前言
LeakCanary 不多做介绍了,用过的都知道是来干嘛的,不多比比。
https://square.github.io/leakcanary/
少废话,我也懒得打,以下简称LC。
1.正题
我们在LC 1.* 的版本需要进行额外的init操作
一般是在Application的onCreate方法调用
install()
有时候还要进行inMainProcess()的判断。
LC 2.*版本现在无感install,今天就是从源码角度来分析。
很多博文都有说到,LC 2.* 是借助contentProvider 的onCreate方法调用时机比application的onCreate调用早,这个特征实现。
但是也没说为啥。口可口可。
2.操作
既然是ContentProvider,Android 四大组件之一,ContentProvider声明必然在AndroidManifest.xml里,我们就去清单文件去找,可是问题来了
LC 2.*的包结构
找哪个module的清单?LC 是采用的清单合并的方法(虽然这是我听说的)
我当时是看了这篇博文
https://www.jianshu.com/p/3b429c38e73e
采用的取巧的办法,全局搜索 install(
找到了关键类。
这里提供一个小技巧
打开app demo的AndroidManifest.xml
点击merged manifest(可以查看最终合成的清单文件)
image.png
看到了关键类名
AppWatcherInstaller.
3.初始化源码
image.pngAppWatcherInstaller继承自 ContentProvider
onCreate方法里实现
image.png
以上就是免初始化的根本原因了。
下文就是跟踪一下流程。
4.上下文的初始化
我会去关注这个上下文的初始化,是因为我在处理LC 自定义Config的时候,有一个onHeapAnalyzedListener
onHeapAnalyzedListener
我发现这个默认listener的create方法内部传了一个application
image.png当时不知道这个application是怎么传进来的,因为还没分析这个免初始化操作。
image.png invoke方法
这个invoke方法的调用时机
image.png
install后,调用了这个invoke方法(就是理解成一个interface)
image.png
不巧呢,InternalLeakCanary就实现了这个interface,反射找到这个类
image.png最终完成了InternalLeakCanary的invoke方法调用。
按时间上顺序整理一下
1.启动app;
2.AppWatcherInstaller这个contentProvider的onCreate方法;
3.InternalAppWatcher的init方法,通过反射的方式找到InternalLeakCanary类,并且初始化onAppWatcherInstalled;
4.InternalAppWatcher的install方法;
5.InternalLeakCanary完成invoke方法,给application赋值;
5.一些问题
问题1:LC 2.* 为什么不提供no-op?
大意就是用debugImcomplemation就行了
https://github.com/square/leakcanary/issues/979
问题2:如果要在代码里加 install 代码,势必会 import 包,如果没有LC no-op包,编译会出现class not found的问题,这种怎么解决?
我尝试提供了一个no-op包
https://github.com/lamster2018/EmptyLeakCanary
问题3:为什么要做inMainProcess的判断?
image.png
母鸡。
问题4:多进程下,ContentProvider会init多次么?
就一个contentProvider的实例
https://blog.csdn.net/weixin_34252686/article/details/87964067
网友评论