该系列文章总纲链接:专题分纲目录 android 开机启动流程分析


本章关键点总结 & 说明:

这里因为整体的导图太大,因此截取一部分 ,方便大家看的清楚:

android 开机启动流程分析(16)Launcher启动_调用栈

在上图中关注➕“launcher启动”部分即可。同时,下面的图是开机启动流程分析 持续迭代的效果,可放大观看。

android 开机启动流程分析(16)Launcher启动_调用栈_02

在SystemServer启动后,SystemServer又启动了AMS,同时在SystemServer中关键方法 startOtherServices 中

private void startOtherServices() {
		//...
		final AudioService audioServiceF = audioService;
        mActivityManagerService.systemReady(new Runnable() {//这里会回调
            @Override
            public void run() {
                Slog.i(TAG, "Making services ready");
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY);

                try {
                    mActivityManagerService.startObservingNativeCrashes();
                } catch (Throwable e) {
                    reportWtf("observing native crashes", e);
                }

                Slog.i(TAG, "WebViewFactory preparation");
                WebViewFactory.prepareWebViewInSystemServer();

                try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
				//...
                try {
                    if (mmsServiceF != null) mmsServiceF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying MmsService running", e);
                }
            }
       });	

1 这里专注AMS的SystemReady方法,实现如下:

public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
            if (mSystemReady) {
                // If we're done calling all the receivers, run the next "boot phase" passed in
                // by the SystemServer
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }
			//...
			/**startHomeActivityLocked调用栈
				mStackSupervisor.startHomeActivity(intent, aInfo, reason);
					moveHomeStackTaskToTop
					startActivityLocked,这里接下来启动Activity的启动流程
			*/
			startHomeActivityLocked(mCurrentUserId, "systemReady");
			//...
		}
	}

这里在startHomeActivityLocked之后 便开始 执行 Activity的启动流程了,因为这里涉及的函数调用层数比较多,这里整理了一下startHomeActivityLocked的调用栈,如下所示:

/**startHomeActivityLocked调用栈*/
	ActivityStackSupervisor:
	mStackSupervisor.startHomeActivity(intent, aInfo, reason);
	    moveHomeStackTaskToTop->startActivityLocked,这里接下来启动Activity的启动流程
			startActivityUncheckedLocked
			resumeTopActivityLocked
	-------------------------------------------------------
	ActivityStack:->targetStack.startActivityLocked
		mStackSupervisor.resumeTopActivitiesLocked
			targetStack.resumeTopActivityLocked
			    resumeTopActivityInnerLocked
	---------------------------------------
	ActivityStackSupervisor:
		mStackSupervisor.startSpecificActivityLocked
			mService.getProcessRecordLocked
			realStartActivityLocked
			mService.startProcessLocked //创建 ActivityThread线程

 在这里,最后 调用的 startProcessLocked方法,目的就是 创建ActivityThread线程

2 创建ActivityThread线程流程如下:

mService.startProcessLocked //创建 ActivityThread线程
	Process.start
		startViaZygote
			zygoteSendArgsAndGetResult

3 最后在ActivityThread 启动后,执行main方法,分析如下

public static void main(String[] args) {
        SamplingProfilerIntegration.start();
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());
        Security.addProvider(new AndroidKeyStoreProvider());
		
        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
		
        Process.setArgV0("<pre-initialized>");
		//创建looper对象,与本线程绑定,在activity或service或dialog中可以随便使用handler是这个线程在后台
        Looper.prepareMainLooper();
		//创建ActicityThread对象实例,当new ActivityThread()进行时,其成员变量ApplicationThread同时被创建
        ActivityThread thread = new ActivityThread();
		/**进行attach回调,调用栈如下:
			mgr.attachApplication(mAppThread); 
			这里走的是binder通信->call AMS:attachApplication->attachApplicationLocked
		*/
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

4 这里最为关键的一个步骤是attach,这里详细分析下:

   private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }
		//...
        app.makeActive(thread, mProcessStats);
        //...
        try {
            //...
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            // ...
            return false;
        }
        //...
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                //...
            }
        }
		//...
        return true;
    }

这里代码做了大部分的删减,主要表明这里做了4件事情,分别是

  1.     PID->ProcessRecord
  2.     thread->注册app记录
  3.     thread与PID绑定
  4.     call mStackSupervisor.attachApplicationLocked->realStartActivityLocked

通过attach,ActivityThread的ApplicationThread.scheduleResumeActivity触发显示,到此 Launcher 的Activity也就启动并显示出来了