Application creation process analysis of App startup

Application optimization is indispensable during cold start optimization, so this article is a study of the Application creation process. Zygote instantiates ActivityThread after creating the application process, and the main method of ActivityThread creates the process of Application. Open frameworks/base/core/java/android/app/ActivityThread.java  and we start to analyze from the main method of ActivityThread.java:

public static void main(String[] args) {

        ...
        //初始化主线程的Looper
        Looper.prepareMainLooper();
        
        ...
        //实例化一个ActivityThread
        ActivityThread thread = new ActivityThread();
        //需要关注的方法
        thread.attach(false, startSeq);

        ...
        //在主线程中运行消息队列
        Looper.loop();
    }

The Handler mechanism is used in the main method, first initialize Looper, then instantiate an ActivityThread object, which has a final modified H internal class (this class inherits Handler) and instantiate it, and finally call Looper.loop() to start The message loop of the main thread.

Then look at the code executed by thread.attach(false, startSeq):

  private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;//是否是系统进程
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            //在RuntimeInit中设置ApplicationThread的Binder
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //获取AMS服务
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //调用AMS服务的attachApplication来启动一个Application, 需要关注的方法
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...

        } else {
            //系统进程的处理
            ...
        }

    }

In the attach method of ActivityThread, call attachApplication of AMS service to start an Application. Next, let's look at mgr.attachApplication(mAppThread, startSeq). Open ActivityManagerService.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        
        ...

        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

The attachApplicationLocked method calls ActivityThread.bindApplication(), and finally creates an Application through bindApplication().

 public final void bindApplication(String processName, ApplicationInfo appInfo,
                ProviderInfoList providerList, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
            
            ...

            //生成AppBindData对象,设置Application的初始化信息。
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providerList.getList();
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            data.autofillOptions = autofillOptions;
            data.contentCaptureOptions = contentCaptureOptions;
            data.disabledCompatChanges = disabledCompatChanges;
            //通过Handler机制发送消息
            sendMessage(H.BIND_APPLICATION, data);
        }

The H in the ActivityThread mentioned at the beginning can process the BIND_APPLICATION message through handleMessage:

public void handleMessage(Message msg) {
           
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
               ...
            }
}

Take a look at what handleBindApplication() does...

private void handleBindApplication(AppBindData data) {
        // Register the UI Thread as a sensitive thread to the runtime.
        VMRuntime.registerSensitiveThread();
        
        //进程启动的时间 
        Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());

        ...
        // 进程名称
        Process.setArgV0(data.processName);
        //APP 名称
        android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                data.appInfo.packageName,
                                                UserHandle.myUserId());
        //包名
        VMRuntime.setProcessPackageName(data.appInfo.packageName); 

        //在P之前,内部调用解码bitmap使用了BitmapFactory;之后使用ImageDecoder以节省内存
        ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion;

        //重置系统时区
        TimeZone.setDefault(null);
 
        ...
        //生成LoadedApk对象
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        //debug设置
        updateDebugViewAttributeState();

        //创建Instrumentation对象,并执行init初始化
        final InstrumentationInfo ii;
             
            ii = new ApplicationPackageManager(
                        null, getPackageManager(), getPermissionManager())
                        .getInstrumentationInfo(data.instrumentationName, 0);
           
       //反射创建Application对象
        Application app;
        
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

        //启动Instrumentation线程
        mInstrumentation.onCreate(data.instrumentationArgs);

        //调用Application对象的onCreate方法。
        mInstrumentation.callApplicationOnCreate(app);
    }

Next, look at the newApplication() method finally called by the last Instrumentation class. This method first loads the class name corresponding to the Application through the ClassLoader object, and calls the attach method of the Application object through reflection.

/frameworks/base/core/java/android/app/Instrumentation.java

 public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        //反射调用Application对象的attach方法
        app.attach(context);
        return app;
    }
    
    
    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

The callApplicationOnCreate method is called in handleBindApplication(), and the onCreate method of Application is called through reflection.

public void callApplicationOnCreate(Application app) {
    //通过反射调用application的onCreate方法
    app.onCreate();
}

Come here, the attach() method and onCreate() method of Application are executed, it can be seen that the attach() method is executed earlier. The place where we perform cold start optimization is also in the Application life cycle.
 

Guess you like

Origin blog.csdn.net/weixin_43858011/article/details/124494616