Application 初始化流程

Application 的 onCreate 和 attachBaseContext

Application 的 onCreate 和 attachBaseContext 是 Application 的两个回调方法,通常我们会在其中做一些初始化操作。

onCreate 和 attachBaseContext 顺序: Application 的 attachBaseContext 在 onCreate 之前执行。

handleBindApplication

App 的 application 创建是在 ActivityThread 的 handleBindApplication 方法完成的。

  private void handleBindApplication(AppBindData data) {
     ....
     final InstrumentationInfo ii;
     ....
     if (ii != null) {
       //1.创建ContentImpl
       final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
            try {
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiate instrumentation "
                    + data.instrumentationName + ": " + e.toString(), e);
            }
        //2.创建Instrumentation
      final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        ....
        //3.创建Application对象
         Application app;
         app = data.info.makeApplication(data.restrictedBackupMode, null);
         // Propagate autofill compat state
            app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);
            mInitialApplication = app;
        ...
        //4.启动当前进程中的ContentProvider和调用其onCreate方法
        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);
                }
            }
        //5.调用Application的onCreate方法
        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);
                }
            }
    }
 }

可以看到初始化顺序: 1.创建ContentImpl -> 2.创建Instrumentation -> 3.创建Application对象 并调用 attachBaseContext方法 -> 4.启动当前进程中的ContentProvider和调用其onCreate方法 -> 5.调用Application的onCreate方法

总结

Application 的 attachBaseContext 在 onCreate 之前执行。attachBaseContext 中拿到了创建的 ContextImpl,但是此时 Application 没有创建完成,比如 mLoadedApk 的赋值还没有执行。此时如果在 attachBaseContext 中调用 this.getApplicationContext,也会返回空,因为 application 还没有创建完成。等到回调了 onCreate 时,Application 才算真正构造完毕。

如果项目中的初始化都是同步初始化的话,并且使用到了多个ContentProvider,App Startup 还是不错的,毕竟统一到了一个ContentProvider中,同时支持了简单的顺序依赖。

但是如果在追求App性能与启动速度的场景中,多个SDK同时利用各自定义的ContentProvider实现“自启动”, 在各种有先后顺序与依赖的SDK初始化下做优化,那么 App Startup 就不是很好用了。也正式这个原因,目前不建议将 App Startup 用于生产环境中。

目前的推荐方案还是之前我们都使用过的:同步+异步初始化,并通过有向无环图拓扑排序的方式; Anchors

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值