LeakCanary 2.0后 为什么不需要在application中调用install,跟Application的启动流程有什么关系

LeakCanary 2.0后 为什么不需要在application中调用install

用过 LeakCanary 的都知道,在版本2.0之前需要调用LeakCanary.install()来开启组件的功能以便监听内存泄露。但是在2.0版本之后不需要手动调用了,直接依赖架包就可以使用leak的功能了。这是怎么做到的?难道Leak不需要初始化了?当然不是。要说清这个需要我们先来了解app的启动流程。

Application的启动流程

LeakCanary.png

从图片我们分析app启动流程如下步骤

  • 点击图片的时候launch进程通过binder和AMS通信启动一个activity
  • AMS收到启动的消息后以socket的方式通信Zygote进程fork一个app进程
  • app进程启动后,创建ActivityThread,Looper、Handler对象,开启主线程消息循环Looper.loop()。
  • ActivityThread通过AMS的代理对象ActivityManagerProxy以binder的方式通信AMS
  • AMS接收到信息,调用attachApplication方法
  • AttachApplication方法中,AMS分别通过bindApplication、scheduleLaunchActivity方法,通知APP进程的主线程Handler,对APP进程的Application和Activity进行初始化,并执行Application、Activity的生命周期。

当Activity启动完成后,整个application的启动流程完毕。那么这跟我们的LeakCanary不主动初始化有什么关系呢?

不着急,关键就在bindApplication方法中。来看看bindApplication中的关键代码。

bindApplication中的关键代码

private void handleBindApplication(AppBindData data) {  
   
 VMRuntime.registerSensitiveThread();  
 
  //.........     省略中间代码  
 
if (!data.restrictedBackupMode) {  
               if (!ArrayUtils.isEmpty(data.providers)) {  
                   installContentProviders(app, data.providers);  
                    // For process that contains content providers, we want to  
                    // ensure that the JIT is enabled "at some point".  
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);  
                }  
            }  
  
            // Do this after providers, since instrumentation tests generally start their  
            // test thread at this point, and we don't want that racing.  
            try {  
                mInstrumentation.onCreate(data.instrumentationArgs);  
            } catch (Exception e) {  
                throw new RuntimeException(  
                    "Exception thrown in onCreate() of "  
                    + data.instrumentationName + ": " + e.toString(), e);  
            }  
            try {  
                mInstrumentation.callApplicationOnCreate(app);  
            } catch (Exception e) {  
                if (!mInstrumentation.onException(app, e)) {  
                    throw new RuntimeException(  
                      "Unable to create application " + app.getClass().getName()  
                      + ": " + e.toString(), e);  
                }  
            }  
 //.........     省略后面的代码  
}  

仔细看这句代码mInstrumentation.callApplicationOnCreate(app)其实最终调用到了ApplicationonCreate方法之中。往前看你会看到这样一句代码。installContentProviders(app, data.providers) 这句代码实现了ContentProviders的安装,所以app定义的provider都是优先于application的oncreate执行的。

在LeakCanary2.0以后就把初始化方法放在了ContentProvider中。来看看这个provider的实现。

LeakCanary 的初始化位置

在LeakCanary2.0以后就把初始化方法放在了ContentProvider中。来看看这个provider的实现。


internal sealed class AppWatcherInstaller : ContentProvider() {

  /**
   * [MainProcess] automatically sets up the LeakCanary code that runs in the main app process.
   */
  internal class MainProcess : AppWatcherInstaller()

  /**
   * When using the `leakcanary-android-process` artifact instead of `leakcanary-android`,
   * [LeakCanaryProcess] automatically sets up the LeakCanary code
   */
  internal class LeakCanaryProcess : AppWatcherInstaller()

  override fun onCreate(): Boolean {
    val application = context!!.applicationContext as Application
    AppWatcher.manualInstall(application)
    return true
  }
    //......省略其他代码
}

可以看到在onCreate中调用了AppWatcher.manualInstall()来初始化LeakCanary

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容