使用 添加依赖(release 有 no-op 版)然后在 Application 初始化。
1 2 3 4 5 6 dependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.X' releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.X' debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.X' }
1 2 3 4 5 6 7 8 9 10 11 12 13 public class ExampleApplication extends Application { @Override public void onCreate () { super .onCreate(); if (LeakCanary.isInAnalyzerProcess(this )) { return ; } LeakCanary.install(this ); } }
原理 Watch Activity:
application.registerActivityLifecycleCallbacks 覆写 onActivityDestroyed
watch()使用 WeakReference + ReferenceQueue 监听对象回收情况
watchedObjects(LinkedHashMap<key, KeyedWeakReference>) watch() 方法传进来的引用,尚未判定为泄露 queue(ReferenceQueue) 怀疑泄漏的对象列表
以 UUID.randomUUID().toString() 为 key 构造 KeyedWeakReference(关联 ReferenceQueue) 存入 watchedObjects。
弱引用一旦变得弱可达,就会立即入队 ReferenceQueue。这将在 finalization 或者 GC 之前发生。
watch 方法最后会调用 moveToRetained()
Dump Analysis 计算了到 GC Roots 的最短强引用路径。
2.0 版本 不需要在 Application 初始化 1 2 3 dependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.X' }
ContentProvider 实现 leakcanary-android-process 模块的 AndroidManifest.xml 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="com.squareup.leakcanary" > <application > <service android:name ="leakcanary.internal.HeapAnalyzerService" android:exported ="false" android:process =":leakcanary" /> <provider android:name ="leakcanary.internal.AppWatcherInstaller$LeakCanaryProcess" android:authorities ="${applicationId}.leakcanary-process.installer" android:process =":leakcanary" android:exported ="false" /> </application > </manifest >
看看 AppWatcherInstaller 干了啥:
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 internal sealed class AppWatcherInstaller : ContentProvider () { internal class MainProcess : AppWatcherInstaller () internal class LeakCanaryProcess : AppWatcherInstaller () { override fun onCreate () : Boolean { super .onCreate() AppWatcher.config = AppWatcher.config.copy(enabled = false ) return true } } override fun onCreate () : Boolean { val application = context!!.applicationContext as Application InternalAppWatcher.install(application) return true } }
利用加载顺序实现自动注入:
Application->attachBaseContext =====> ContentProvider->onCreate =====> Application->onCreate =====> Activity->onCreate
优点:实现”免侵入”集成,不需要手动初始化。 缺点:无法更改初始化时机(App 启动优化按需延迟初始化第三方库对这样的集成方式就无能为力了)。考虑到 LeakCanary 是开发 debug 阶段使用的,也无可厚非。一般的 SDK 还是不建议使用这种方式。
添加默认对 Fragment 的支持 Fragment:
Android O 版本 androidx 都具备对 Fragment 生命周期的监听功能。
application.registerActivityLifecycleCallbacks 覆写 onActivityCreated 然后 fragmentManager.registerFragmentLifecycleCallbacks 覆写 onFragmentViewDestroyed() onFragmentDestroyed()