网上大牛太多,不敢说分析,也不敢装成大大,所以只能是浅析…
那么今天这篇主要解决什么问题呢?其实就一个问题,LeakCanay.install(this)这个函数到底是怎么走的,用测试的话说就是数据流是怎么走的,用探索性测试的方法说就是:快递法。
LeakCanay项目的地址是:https://github.com/square/leakcanary
那么经过半天的下载之后,成功导入到as中。
直接从入口函数分析:LeakCanary.install(this),那么打算是分四个部分分析,第一部分分析入口,第二部分分析怎么判断泄漏,第三部分是对内存快照的处理,第四部分是总结和扩展,东西不多,鉴于我自己的水平只能看一点算一点了 :)
一、函数入口和常用类分析
public static RefWatcher install(Application application) {
return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
.excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
.buildAndInstall();
}
那么install静态方法里面包含了3个方法,这3个方法都是通过AndroidRefWatcherBuilder这个辅助类来配置相关信息的:
listenerServiceClass方法是和结果分析相关的服务绑定,绑定到DisplayLeakService.class这个类上面,这个类负责通知泄漏消息给你
excludedRefs方法是排除一些开发可以忽略的泄漏路径(一般是系统级别BUG),这些枚举在AndroidExcludedRefs这个类当中定义
buildAndInstall这才是重点方法,所以看下:
public RefWatcher buildAndInstall() {
RefWatcher refWatcher = build();
if (refWatcher != DISABLED) {
LeakCanary.enableDisplayLeakActivity(context);
ActivityRefWatcher.installOnIcsPlus((Application) context, refWatcher);
}
return refWatcher;
}
上面没啥了,无非就是实例化RefWatcher对象,这个对象是用来判断泄漏对象的,马上会说
所以直接看ActivityRefWatcher.installOnIcsPlus方法:
public static void installOnIcsPlus(Application application, RefWatcher refWatcher) {
if (SDK_INT < ICE_CREAM_SANDWICH) {
// If you need to support Android < ICS, override onDestroy() in your base activity.
return;
}
ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher);
activityRefWatcher.watchActivities();
}
嗯,已经跳转到了ActivityRefWatcher这个类,这个类提供了下面这个api:
public void watchActivities() {
// Make sure you don't get installed twice.
stopWatchingActivities();
application.registerActivityLifecycleCallbacks(lifecycleCallbacks);
}
所以核心方法找到了,就是registerActivityLifecycleCallbacks这个方法,这是application提供的一个方法,用来统一管理所有activity的生命周期,LeakCanay是在onDestory()方法实现监控的:
private final Application.ActivityLifecycleCallbacks lifecycleCallbacks =
new Application.ActivityLifecycleCallbacks() {
@Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override public void onActivityStarted(Activity activity) {
}
@Override