leakcanary的自动初始化


目前v2.5版本,已经无需显式的进行初始化了.

由于Android中ContentProvider的onCreate()会在Application的onCreate()之前执行,因此可以在ContentProvider中进行初始化.

恰好有这么一个ContentProvider: AppWatcherInstaller:

internal sealed class AppWatcherInstaller : ContentProvider() {

  internal class MainProcess : AppWatcherInstaller()

  // 当使用leakcananry-android-process包的时候使用,作用是在单独的进程中运行leakcanary
  internal class LeakCanaryProcess : AppWatcherInstaller()

  override fun onCreate(): Boolean {
    val application = context!!.applicationContext as Application
    AppWatcher.manualInstall(application)
    return true
  }

  //... 一些不需要的query,insert逻辑
}

目前有两种选择:

  • 使用leakcanary-android : leakcanary运行在应用进程中

  • 使用leakcanary-android-process : leakcanary运行在单独的进程中:

    <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>
    

Kotlin中 internal修饰符表示包内可见,内部类用internal则表示对能看到外部类的任何本模块的代码都可见

sealed是密封类,类比Java中的枚举类,可以有子类,但是必须在同一个文件中声明(只是拓展的子类不受这个限制);

selaed类是自身抽象的,不能直接实例化,并且可以拥有abstract成员,它不允许有非private构造函数(它的默认构造函数是private的);

那初始化里做了什么呢?

  val objectWatcher = ObjectWatcher(
      clock = clock,
      checkRetainedExecutor = checkRetainedExecutor,
      isEnabled = { true }
  )

  fun install(application: Application) {
    val configProvider = { AppWatcher.config }
    // 监控Activity内存泄漏
    ActivityDestroyWatcher.install(application, objectWatcher, configProvider)

    // 监控Fragment内存泄漏
    FragmentDestroyWatcher.install(application, objectWatcher, configProvider)

    // 库的内部逻辑
    onAppWatcherInstalled(application)
  }

三件事:

  • Activity内存泄漏监控
  • Fragment内存泄漏监控
  • 内部逻辑(暂时不好分类,后续再讲)

如果不想进行自动初始化怎么办?

可以覆盖一个属性:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
      <bool name="leak_canary_watcher_auto_install">false</bool>
    </resources>

为什么?

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.squareup.leakcanary.objectwatcher"
    >

  <application>
    <provider
        android:name="leakcanary.internal.AppWatcherInstaller$MainProcess"
        android:authorities="${applicationId}.leakcanary-installer"
        android:enabled="@bool/leak_canary_watcher_auto_install"
        android:exported="false"/>
  </application>
</manifest>

可以看到enable属性是与leak_canary_watcher_auto_install绑定的.


文章作者: 姜康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜康 !
评论
  目录