目录
- 废话
- 正题
- 搜索关键方法
- 初始化原理
- 上下文赋值流程
- 一些问题
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里,我们就去清单文件去找,可是问题来了
找哪个module的清单?LC 是采用的清单合并的方法(虽然这是我听说的)
我当时是看了这篇博文
https://www.jianshu.com/p/3b429c38e73e
采用的取巧的办法,全局搜索 install(
找到了关键类。
这里提供一个小技巧
打开app demo的AndroidManifest.xml
点击merged manifest(可以查看最终合成的清单文件)
看到了关键类名
AppWatcherInstaller.
3.初始化源码
AppWatcherInstaller继承自 ContentProvider
onCreate方法里实现
以上就是免初始化的根本原因了。
下文就是跟踪一下流程。
4.上下文的初始化
我会去关注这个上下文的初始化,是因为我在处理LC 自定义Config的时候,有一个onHeapAnalyzedListener
我发现这个默认listener的create方法内部传了一个application
当时不知道这个application是怎么传进来的,因为还没分析这个免初始化操作。
这个invoke方法的调用时机
install后,调用了这个invoke方法(就是理解成一个interface)
不巧呢,InternalLeakCanary就实现了这个interface,反射找到这个类
最终完成了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的判断?
母鸡。
问题4:多进程下,ContentProvider会init多次么?
就一个contentProvider的实例
https://blog.csdn.net/weixin_34252686/article/details/87964067