leakcanary原理分析
Posted dfqin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leakcanary原理分析相关的知识,希望对你有一定的参考价值。
1、无代码集成原理
目前最新版本是2.8.1,看文档从2.0版本集成时就不需要修改任何代码了,只需要在build.gradle里面添加一行引用:
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.xxxx'
debugImplementation保证了只在debug环境引入,关于初始化,我们在源码中看到在AndroidManifest.xml中配置了一个provider:
<provider
android:name="leakcanary.internal.MainProcessAppWatcherInstaller"
android:authorities="$applicationId.leakcanary-installer"
android:enabled="@bool/leak_canary_watcher_auto_install"
android:exported="false"/>
而在provider中我们可以看到初始化代码:
override fun onCreate(): Boolean
val application = context!!.applicationContext as Application
AppWatcher.manualInstall(application)
return true
通过相关资料可以知道,provider会在application的onCreate调用之前初始化,所以在provider中对leakcanary初始化,跟手动在application中初始化基本一致。
2、内存泄露监控原理
默认只监控Activity、Fragment、RootView、Service类型的泄露,而这些类型对象有类似与声明周期的节点,知道对象需要释放了。在这个节点,例如Activity的onDestroy(),在这个声明周期后,这个对象就需要释放了,此时对此对象进行监控,看5秒后有没有释放,如果没有释放的话,会触发GC后再判断,如果还没有释放,会认为此对象存在内存泄露,leakcanary会手机泄露信息展示出来。
关于怎么监控一个对象有没有释放,是利用了WeakReference的一个特性,就是创建弱引用时指定一个引用队列(ReferenceQueue),当引用的对象被回收,虚拟机会把此弱引用加入到关联的引用队列中。通过ReferenceQueue中的内容,可以判断对象是否被回收。
3、不同对象监控实现
Activity的监控是通过注册声明周期回调,监听activity销毁时,开始对activity开始监控
private val lifecycleCallbacks =
object : Application.ActivityLifecycleCallbacks by noOpDelegate()
override fun onActivityDestroyed(activity: Activity)
reachabilityWatcher.expectWeaklyReachable(
activity, "$activity::class.java.name received Activity#onDestroy() callback"
)
override fun install()
application.registerActivityLifecycleCallbacks(lifecycleCallbacks)
Fragment的监控同样是通过注册声明周期回调:
override fun invoke(activity: Activity)
val fragmentManager = activity.fragmentManager
fragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true)
override fun onFragmentDestroyed( fm: FragmentManager, fragment: Fragment)
reachabilityWatcher.expectWeaklyReachable(
fragment, "$fragment::class.java.name received Fragment#onDestroy() callback")
View是监控onViewDetachedFromWindow()调用:
rootView.addOnAttachStateChangeListener(object : OnAttachStateChangeListener
val watchDetachedView = Runnable
reachabilityWatcher.expectWeaklyReachable(
rootView, "$rootView::class.java.name received View#onDetachedFromWindow() callback"
)
override fun onViewDetachedFromWindow(v: View)
mainHandler.post(watchDetachedView)
)
Android ContentProvider 初始化过程 - 知乎
以上是关于leakcanary原理分析的主要内容,如果未能解决你的问题,请参考以下文章