LeakCannary原理分析

上篇写到 leakcanary 的使用,这篇主要是了解LeakCannary 大概是如何工作的。

1.首先它是如何监听Activity 销毁的?

因为我们知道只有当activity 销毁(onDestroy())的时候,我们才能对这个activity 进行分析查看哪些对象可能存在内存泄漏。

发现了如下代码:

1
2
3
4
5
public static RefWatcher install(Application application) {
return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
.excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
.buildAndInstall();
}

buildAndInstall() 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public RefWatcher buildAndInstall() {
....
if (refWatcher != DISABLED) {
if (watchActivities) {
//这是观察activity的
ActivityRefWatcher.install(context, refWatcher);
}
if (watchFragments) {
FragmentRefWatcher.Helper.install(context, refWatcher);
}
}
LeakCanaryInternals.installedRefWatcher = refWatcher;
return refWatcher;
}

1
2
3
4
5
6
7
8
public final class ActivityRefWatcher {
....
public static void install(Context context, RefWatcher refWatcher) {
Application application = (Application) context.getApplicationContext();
ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher);
//拿到application,注册activity的生命周期回调
application.registerActivityLifecycleCallbacks(activityRefWatcher.lifecycleCallbacks);
}

其中这个:lifecycleCallbacks 就是回调监听

1
2
3
4
5
6
private final Application.ActivityLifecycleCallbacks lifecycleCallbacks =
new ActivityLifecycleCallbacksAdapter() {//监听activity销毁
@Override public void onActivityDestroyed(Activity activity) {
refWatcher.watch(activity);
}
};

那么我们也可以通过application 注册获取activity 的生命周期监听回调,如下是我写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class LifeCircleActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.life_layout);

final Application application = (Application) getApplicationContext();
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("xx","activity is onActivityCreated...");
}

@Override
public void onActivityStarted(Activity activity) {
Log.i("xx","activity is onActivityStarted...");
}

@Override
public void onActivityResumed(Activity activity) {
Log.i("xx","activity is onActivityResumed...");
}

@Override
public void onActivityPaused(Activity activity) {
Log.i("xx","activity is onActivityPaused...");
}

@Override
public void onActivityStopped(Activity activity) {
Log.i("xx","activity is onActivityStopped...");
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.i("xx","activity is onActivitySaveInstanceState...");
}

@Override
public void onActivityDestroyed(Activity activity) {

application.unregisterActivityLifecycleCallbacks(this);
Log.i("xx","activity is onDestroy...");
}
});
}

这样我们就可以监听我们当前这个类的生命周期了,可以运行打印日志就知道了。

2.内存泄漏的对象的引用路径

这块使用到了 square 的另一个开源库 haha ,获取当前内存中的heap堆信息的snapshot

-------------本文结束感谢您的阅读-------------