App启动之Application创建流程分析

在冷启动优化的时候少不了对Application的优化,所以这一篇文章是对Application的创建流程的学习。Zygote创建应用程序进程后实例化ActivityThread,ActivityThread的main方法创建Application的流程。打开frameworks/base/core/java/android/app/ActivityThread.java 我们从ActivityThread.java的main方法开始分析:

public static void main(String[] args) {

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

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

在main方法中使用了Handler机制,先初始化Looper,然后实例化一个ActivityThread对象,该对象中有final修饰的H内部类(该类继承Handler)并进行了实例化,最后调用Looper.loop()开启了主线程的消息循环。

接着看一下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 {
            //系统进程的处理
            ...
        }

    }

在ActivityThread的attach方法中调用AMS服务的attachApplication来启动一个Application,接下来我们看一下mgr.attachApplication(mAppThread, startSeq)。打开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);
        }
    }

attachApplicationLocked方法调用了ActivityThread.bindAppication(),最终通过bindApplication()创建Application。

 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);
        }

最开始提到的ActivityThread中的H就可以通过handleMessage对BIND_APPLICATION消息进行处理:

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;
               ...
            }
}

看一下handleBindApplication()做了什么...

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);
    }

接下来看最后一个Instrumentation类最终调用的newApplication()方法,该方法首先通过ClassLoader对象加载Application所对应的类名,通过反射调用Application对象的attach方法。

/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;
    }

handleBindApplication()中调用callApplicationOnCreate方法,通过反射调用Application的onCreate方法。

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

走到这里,Application的attach()方法和onCreate()方法执行,可以看出attach()方法更早执行。我们进行冷启动优化的地方也就在Application的生命周期中。
 

猜你喜欢

转载自blog.csdn.net/weixin_43858011/article/details/124494616