Zygote冷启动 启动时间收集(一)

冷启动 启动时间收集

上一篇说道Zygote启动流程,本篇描述冷启动时间收集

  • 首先我们知道冷启动会先初始化Application
  • Application有两个回调,一个是attachBaseContext,一个是onCreate,那么哪个优先级最高呢?
  • 首先看ActivityThread
 private void handleBindApplication(AppBindData data) {
        ...
        // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
        // implementation to use the pool executor.  Normally, we use the
        // serialized executor as the default. This has to happen in the
        // main thread so the main looper is set right.
        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        ...
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        updateLocaleListFromAppContext(appContext,
                mResourcesManager.getConfiguration().getLocales());
        ...
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
// 这里实际上调用的就是application的onattatchContext方法
            app = data.info.makeApplication(data.restrictedBackupMode, null);

            ...
            mInitialApplication = app;
            ...
            try {
                //这里实际上就是调用application的onCreate方法
                mInstrumentation.callApplicationOnCreate(app);
            ...
    }

从源码可知,data.info.makeApplication,是通过LoadedApk的makeApplication,来构造Application

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        ...
        return app;
    }

跟踪源码可知,是Instrumentation在创建application,Instrumentation的newApplication如下

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }

Application 的attatch源码如下

@UnsupportedAppUsage
    /* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }

从这里可以看出先调用了attachBaseContext,最后再赋值给loadApk。

最后分析什么时候调用Application调用onCreate方法

private void handleBindApplication(AppBindData data) {
        ...
       
        ...
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
// 这里实际上调用的就是application的onattatchContext方法
            app = data.info.makeApplication(data.restrictedBackupMode, null);

            ...
            mInitialApplication = app;
            ...
            try {
                //这里实际上就是调用application的onCreate方法
                mInstrumentation.callApplicationOnCreate(app);
            ...
    }

根据上述源码,可以知道mInstrumentation.callApplicationOnCreate(app);最后执行

总结:
Application 的 attachBaseContext 在 onCreate 之前执行。实际完成Application的初始化应该在回调了onCreate的时候。
流程:
Activity-----》handleBindApplication----》data.info.makeApplication----》LoadApk.makeApplication---->
mActivityThread.mInstrumentation.newApplication---->Instrumentation.newApplication---> Application.attatch-->Application.attachBaseContext--->mInstrumentation.callApplicationOnCreate(app);--->Application.oncreate()

综上所述,冷启动开始收集启动时间,最早的点,应该在Application的attachBaseContext。

你可能感兴趣的:(Zygote冷启动 启动时间收集(一))