以前知道AMS、PMS這些概念及其功能,開發的過程中也會用到,就是不知道其來源,好奇心害死貓,扒着扒着扒到系統開機啓動這個知識層面上來了,好吧,那今天就說說這個吧!
系統開機啓動過程
Android系統的啓動,主要是指Android手機關機後,長按電源鍵後,Android手機開機的過程。從系統角度看,Android的啓動程序可分爲:
- bootloader引導
- 裝載與啓動Linux內核
- 啓動Android系統
其中啓動Android系統過程又有以下過程:
- 啓動Init進程
- 啓動Zygote
- 啓動SystemServer
- 啓動Launcher
android啓動過程圖示:
zygote
我們知道,Android系統是基於Linux內的。而在Linux系統中,所有的進程都是init進程的子孫進程,也就是說,所有的進程都是直接或者間接地由init進程fork出來的。
系統啓動的時候執行系統啓動腳本system/core/rootdir/init.rc文件,進而觸發app_process程序(system/bin/app_process,它的源代碼位於frameworks/base/cmds/app_process/app_main.cpp文件中,入口函數是main)創建Zygote進程,Zygote進程負責後續Android應用程序框架層的其它進程的創建和啓動工作。
Zygote進程最大意義是作爲一個Socket的Server端,接收着四面八方的進程創建請求。Android中所有的應用進程的創建都是通過Binder機制請求SystemServer進程,SystemServer進程發送socket消息給Zygote進程,統一由Zygote進程創建出來的。
SystemServer
SystemServer也是一個進程,而且是由zygote進程fork出來的。SystemServer主要用於開啓系統重要的一些相關服務,例如:ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)等等,是不是都很熟悉呢?所以SystemServer和Zygote重要級別可以說是平分秋色了。
什麼時候開啓SystemServer
在zygote開啓的時候,會調用ZygoteInit.main()進行初始化:
public static void main(String argv[]) {
...ignore some code...
//在加載首個zygote的時候,會傳入初始化參數,一旦捕獲到參數是“start-system-server”,即可開啓fork SystemServer指令
boolean startSystemServer = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
...ignore some code...
//開始fork我們的SystemServer進程
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
...ignore some code...
}
接下來看一下startSystemServer具體做了什麼
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
...ignore some code...
//上面ZygoteInit.main(String argv[])裏面的argv就是通過這種方式傳遞進來的
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
//fork SystemServer
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}
這個方法主要是爲了開啓SystemServer,這裏做了三件事:
- 準備fork SystemServer相關參數,例如SystemServer進程的進程Id和組Id均爲爲1000,進程名稱爲system_server等。
- fork SystemServer,如果返回pid爲0則創建成功,否者返回-1或者錯誤;
- 調用handleSystemServerProcess()完成SystemServer進程的初始化工作;
SystemServer進程初始化
上邊也說了SystemServer主要用於開啓系統重要的一些相關服務,例如:ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)等等,我們看一下代碼具體的內部走法:
public final class SystemServer {
//zygote的主入口
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
}
private void run() {
...ignore some code...
//創建主線程looper 在當前線程運行
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
//加載本地系統服務庫,並進行初始化
System.loadLibrary("android_servers");
nativeInit();
// 創建系統上下文
createSystemContext();
//初始化SystemServiceManager對象,下面的系統服務開啓都需要調用SystemServiceManager.startService(Class<T>),這個方法通過反射來啓動對應的服務
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//開啓服務
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
...ignore some code...
}
//初始化系統上下文對象mSystemContext,並設置默認的主題,mSystemContext實際上是一個ContextImpl對象。調用ActivityThread.systemMain()的時候,會調用ActivityThread.attach(true),而在attach()裏面,則創建了Application對象,並調用了Application.onCreate()。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
//在這裏開啓了幾個核心的服務,因爲這些服務之間相互依賴,所以都放在了這個方法裏面。
private void startBootstrapServices() {
...ignore some code...
//初始化ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//初始化PowerManagerService,因爲其他服務需要依賴這個Service,因此需要儘快的初始化
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// 現在電源管理已經開啓,ActivityManagerService負責電源管理功能
mActivityManagerService.initPowerManagement();
// 初始化DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//初始化PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
//開啓消息循環
Looper.loop();
...ignore some code...
}
}
SystemServer初始化過程中主要做了以下幾個重大工作:
- 加載本地系統服務庫,系統底層初始化。
- 創建消息循環體Looper,這個就是爲什麼我們在主線程裏面不用寫Looper,就可以處理UI視圖,原來系統已經爲我們做了這件事。
- 創建系統級上下文,在這個過程中創建我們的主線程ActivityThread,獲取系統上下文對象mSystemContext,並設置系統默認主題。
- 創建SystemServiceManager對象,開啓系統服務三連——引導服務、核心服務以及其他服務。
系統級上下文和我們常用的Context是有區別的,主要是用於服務端(系統級主題和其他服務相關的引導),Context到底是個什麼玩意?我在前邊的一篇文章中也有總結,這裏在闡述一遍,Context英文原意是上下文的意思,在平時開發中涉及到的四大組件及資源操作基本上都離不開Context對象。
服務三連開發者我們最關心的就是引導服務,因爲這裏面開啓的都是我們在日常開發中最容易用到的幾個服務:
- ActivityManagerService AMS在Android系統中扮演很重要的角色,主要負責系統中四大組件的啓動、切換、調度及應用進程的管理和調度等工作,其職責與操作系統中的進程管理和調度模塊相類似。
- PowerManagerService PowerManagerService主要服務Android系統電源管理工作,這樣講比較籠統,就具體細節上大致可以認爲PowerManagerService集中處理用戶活動(如點擊屏幕,按電源鍵等)、電量變化、用戶設置(如在Setting中設置省電模式,飛行模式)、插拔充電器(無線衝,有線衝)等。當發生以上事件時,PowerManagerService都要進行各種狀態的更新。
- DisplayManagerService DisplayManagerService用來管理顯示的生命週期,它決定如何根據當前連接的物理顯示設備控制其邏輯顯示,並且在狀態更改時,向系統和應用程序發送通知等等。
- PackageManagerService PackageManagerService(簡稱PMS),是Android系統中核心服務之一,管理着所有跟package相關的工作,常見的比如安裝、卸載應用。
- UserManagerService UserManagerService的主要功能是創建和刪除用戶,以及查詢用戶信息。Android可以支持多個用戶使用系統,通常第一個在系統中註冊的用戶將默認成爲系統管理員。不同用戶的設置各不相同,並且不同用戶安裝的應用及應用數據也不相同。
Launcher
Launcher即桌面,是Android智能設備的窗口,用戶使用最頻繁的軟件之一。Launhcer是Android所有應用的入口,也提供窗口小部件等功能。
Launcher本身就是一個APP,一個提供桌面的APP,Laucher有很多和普通APP不同的地方:
- Launcher是頂部APP,即任何應用返回後都是到Launcher,不能再繼續返回;
- Launcher是所有應用的入口,可以管理應用;
- Launcher是Android系統啓動後就要顯示給用戶的應用。
Launcher是由ActivityManagerService啓動的,在SystemServer.java的startOtherServices()方法裏面的調用 mActivityManagerService.systemReady()進行Launcher的啓動之旅,在systemReady
方法執行過程中調了用startHomeActivityLocked
方法,方法內部通過getHomeIntent
拿到Launcher對應的Intent,最後調用startHomeActivity
來啓動Launcher。
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
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);
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}
}
return true;
}
ActivityManagerService和PackageManagerService一樣,都是在開機時由SystemServer組件啓動,Launcher在啓動的時候會通過PackageManagerServic把系統中已經安裝好的應用程序以快捷圖標的形式展示在桌面上,這樣用戶就可以使用這些應用程序了。另外程序安裝的時候SystemServer組件會通過PackageManagerServic來安裝應用程序,應用程序安裝好了以後會以通知的形式通知launcher展示應用圖標,卸載同理。
總結
本篇簡單分析了一下系統從開機啓動到桌面展示這個過程,這裏簡單總結一下:
- 系統啓動時init進程會創建Zygote進程,Zygote進程負責後續Android應用程序框架層的其它進程的創建和啓動工作。
- Zygote進程會首先創建一個SystemServer進程,SystemServer進程負責啓動系統的關鍵服務(服務三連),例如ActivityThread、AMS、PMS等。
- Android中所有的應用進程的創建都是通過Binder機制請求SystemServer進程,SystemServer進程發送socket消息給Zygote進程,統一由Zygote進程創建出來的。
- AMS啓動Launcher程序,Launcher展示系統相關應用快捷方式。
開機啓動我們重在瞭解過程,明確知道系統幾個重要的服務,瞭解過程中雖然很枯燥但是對開發很有幫助,例如以後的插件化學習,下篇我會着重分析一下Launcher的構造以及Activity的啓動過程,加油,期待。
參考:
- https://blog.csdn.net/luoshengyang/article/details/6768304
- https://www.jianshu.com/p/327f583f970b
- https://www.jianshu.com/p/6037f6fda285