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 初始化过程 - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值