Android系統啓動流程分析之啓動應用

繼上一篇Android系統啓動流程分析之安裝應用文章接着分析系統啓動應用的過程.

Android系統的啓動流程簡要分析裏已經介紹了SystemServer在main方法裏創建了一個線程ServerThread,並調用initAndLoop方法加載各種服務.


ActivityManagerService(Ams)就是在initAndLoop方法裏加載的.那麼,看下initAndLoop方法裏關於AMS的核心代碼.

1.context = ActivityManagerService.main(factoryTest);


2.ActivityManagerService.setSystemProcess();


3.ActivityManagerService.installSystemProviders();


4.ActivityManagerService.self().setWindowManager(wm);


5.ActivityManagerService.self().systemReady


 一步一步進行分析.

1.context = ActivityManagerService.main(factoryTest);

這行代碼是啓動ActivityManagerService,獲取上下文context,進入AMS的main方法看一下

public static final Context main(int factoryTest) {
		AThread thr = new AThread();
		thr.start();
		
		synchronized (thr) {
			while (thr.mService == null) {
				try {
					//線程等待activitymanagerservice初始化完成
					thr.wait();
				} catch (InterruptedException e) {
				}
			}
		}
		ActivityManagerService m = thr.mService;
		mSelf = m;
		//啓動一個主線程
		ActivityThread at = ActivityThread.systemMain();
		
		mSystemThread = at;
		//獲取上下文context
		Context context = at.getSystemContext();
		
		context.setTheme(android.R.style.Theme_Holo);
		m.mContext = context;
		m.mFactoryTest = factoryTest;
		m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());

		//新建一個activity堆棧管理輔助類
		m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);

		m.mBatteryStatsService.publish(context);
		m.mUsageStatsService.publish(context);
		m.mAppOpsService.publish(context);

		synchronized (thr) {
			thr.mReady = true;
			//activitymanagerservice啓動完成
			thr.notifyAll();
		}

		m.startRunning(null, null, null, null);

		return context;
	}

1.1

在mian方法裏會創建一個線程AThread,AThread用來初始化Looper,AThread等待ActivityManagerService初始化完成後把自己的成員變量mService賦值給ActivityManagerService自身.

1.2 

啓動一個主線程ActivityThread,ActivityThread是所有Application運行的主線程,

1.3

獲取上下文context,最終是調用ContextImpl的createSystemContext方法返回的,context本質是ContextImpl的實例

1.4

等ActivityManagerService啓動完成,調用m.startRunning()方法運行,在startRunning方法內部調用systemReady()方法.做系統準備工作.

public final void startRunning(String pkg, String cls, String action, String data) {
		synchronized (this) {
			if (mStartRunning) {
				return;
			}
			mStartRunning = true;
			mTopComponent = pkg != null && cls != null ? new ComponentName(pkg, cls) : null;
			//如果傳入的action爲空那麼賦值Intent.ACTION_MAIN給mTopAction
			mTopAction = action != null ? action : Intent.ACTION_MAIN;
			mTopData = data;
			if (!mSystemReady) {
				return;
			}
		}

		systemReady(null);
	}
這個mTopAction就是後面要啓動第一個Activity,也就是Launcher的Action.

1.4.1

在systemReady方法調用mStackSupervisor.resumeTopActivitiesLocked方法.

public void systemReady(final Runnable goingCallback){
			......
			......
			mStackSupervisor.resumeTopActivitiesLocked();
			......
	}	 
1.4.2

最終經過層層跳轉會回到ActivityManagerService的startHomeActivityLocked方法.

boolean startHomeActivityLocked(int userId) {
		......
		......
		//獲取intent信息
		Intent intent = getHomeIntent();
		
		ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
		if (aInfo != null) {
			intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
			// Don't do this if the home app is currently being
			// instrumented.
			aInfo = new ActivityInfo(aInfo);
			aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
			ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid, true);
			if (app == null || app.instrumentationClass == null) {
				intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
				//啓動主程序,也就是Laucnher
				mStackSupervisor.startHomeActivity(intent, aInfo);
			}
		}
		return true;
	}
1.4.3

通過getHomeIntent方法獲取Intent信息,看下代碼

Intent getHomeIntent() {
		Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
		intent.setComponent(mTopComponent);
		if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
			//設置Category
			intent.addCategory(Intent.CATEGORY_HOME);
		}
		return intent;
	}
給intent設置了Category,這個mTopAction就是前面設置的.

那麼在這裏Intent指定Action爲action.MAIN,category爲category.HOME.這正是啓動Launcher的配置

<intent-filter >
                <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.HOME" />
               
            </intent-filter>
1.4.4

回到1.4.2,調用如下代碼啓動Launcher

//啓動主程序,也就是Laucnher
mStackSupervisor.startHomeActivity(intent, aInfo);


2.ActivityManagerService.setSystemProcess()

這個方法是用來註冊一些服務和獲取、綁定進程信息的.

public static void setSystemProcess() {
		try {
			ActivityManagerService m = mSelf;
			//註冊ActivityManagerService
			ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
			//註冊進程統計服務
			ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
			//註冊內存服務
			ServiceManager.addService("meminfo", new MemBinder(m));
			//註冊圖像處理服務
			ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
			//註冊數據庫服務
			ServiceManager.addService("dbinfo", new DbBinder(m));
			//註冊cpu服務
			if (MONITOR_CPU_USAGE) {
				ServiceManager.addService("cpuinfo", new CpuBinder(m));
			}
			//註冊權限服務
			ServiceManager.addService("permission", new PermissionController(m));
			//獲取應用信息
			ApplicationInfo info = mSelf.mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS);
			//綁定系統應用信息,
			mSystemThread.installSystemApplicationInfo(info);

			synchronized (mSelf) {
				//獲取ProcessRecord實例,ProcessRecord是描述進程信息的
				ProcessRecord app = mSelf.newProcessRecordLocked(info, info.processName, false);
				app.persistent = true;
				app.pid = MY_PID;
				app.maxAdj = ProcessList.SYSTEM_ADJ;
				//調用ProcessStatsService開始記錄process的狀態
				app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
				//把進程名,uid,ProcessRecord實例存到mProcessNames數組中
				mSelf.mProcessNames.put(app.processName, app.uid, app);
				synchronized (mSelf.mPidsSelfLocked) {
					mSelf.mPidsSelfLocked.put(app.pid, app);
				}
				mSelf.updateLruProcessLocked(app, false, null);
				mSelf.updateOomAdjLocked();
			}
		} catch (PackageManager.NameNotFoundException e) {
			throw new RuntimeException("Unable to find android system package", e);
		}
	}
2.1

在ServiceManager裏註冊一些服務,AMS、進程統計服務、內存服務、圖像處理服務、數據庫服務、CPU服務、權限服務

2.2

通過PackageManager獲取應用信息

//獲取應用信息
ApplicationInfo info = mSelf.mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS);

獲取包名爲android的apk的信息,對應的就是framework-res.apk.

2.3

調用以下代碼將獲取到的應用信息綁定到mSystemThread的context上.

mSystemThread.installSystemApplicationInfo(info);
2.4

ActivityManagerService調用newProcessRecordLocked方法創建一個ProcessRecord對象,ProcessRecord紀錄了一個進程的信息,這裏是指systemServer進程


3.ActivityManagerService.installSystemProviders();

這個方法是啓動SettingsProvider的.SettingsProvider相當於系統的一個數據庫.

4.ActivityManagerService.self().setWindowManager(wm);

這個方法是用來設置窗口管理器的.

5.ActivityManagerService.self().systemReady

這個方法是用來做系統準備工作的.

ActivityManagerService.self().systemReady(new Runnable() {
			public void run() {
				Slog.i(TAG, "Making services ready");
				try {
					// 開始監視native是否crash
					ActivityManagerService.self().startObservingNativeCrashes();
				} catch (Throwable e) {
					reportWtf("observing native crashes", e);
				}
				if (!headless) {
					//啓動SystemUi
					startSystemUi(contextF);
				}
				try {
					if (mountServiceF != null)
						mountServiceF.systemReady();
				} catch (Throwable e) {
					reportWtf("making Mount Service ready", e);
				}
				try {
					if (batteryF != null)
						batteryF.systemReady();
				} catch (Throwable e) {
					reportWtf("making Battery Service ready", e);
				}
				try {
					if (networkManagementF != null)
						networkManagementF.systemReady();
				} catch (Throwable e) {
					reportWtf("making Network Managment Service ready", e);
				}
				......
				......

5.1

開始監視native是否crash

5.2

啓動SystemUi

5.3

做各種服務的準備工作,比如掛載管理服務、電腦管理服務、網絡連接管理服務.


結束語:按照上述5大步來就可以慢慢理清啓動應用的流程了.具體細節你們可以自己去探索.











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章