SystemServer進(jìn)程的啟動(dòng)流程
這道題想考察什么?
這道題想考察同學(xué)對(duì)SystemServer進(jìn)程的了解。
考生應(yīng)該如何回答
SystemServer進(jìn)程是由zygote進(jìn)程啟動(dòng)的,它作為zygote進(jìn)程的大兒子,它被賦予了重要的職責(zé),啟動(dòng)并管理app運(yùn)行所需要的絕大多數(shù)服務(wù),其中包含:AMS ,ATMS,WMS,PKMS,PMS等等大概有90多個(gè)服務(wù),這些服務(wù)的啟動(dòng)和管理流程的細(xì)節(jié)請(qǐng)看后面的分析。
1.SystemServer是做什么的
SystemServer進(jìn)程主要是用于創(chuàng)建和管理系統(tǒng)服務(wù)的,例如AMS、WMS、PMS。由于SystemServer進(jìn)程和應(yīng)用進(jìn)程由Zygote進(jìn)程啟動(dòng),所以接下來分析Zygote如何處理的SystemServer進(jìn)程。
2.Zygote處理SystemServer進(jìn)程
繼上一題《Zygote進(jìn)程的啟動(dòng)流程》的代碼,在zygote#main() 函數(shù)中通過調(diào)用forkSystemServer()函數(shù) fork SystemServer 進(jìn)程,那么我們看一下下面的代碼:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
try {
// 1.創(chuàng)建SystemServer進(jìn)程,并返回當(dāng)前進(jìn)程的pid
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
// 2.如果pid==0則說明Zygote進(jìn)程創(chuàng)建SystemServer進(jìn)程成功,當(dāng)前運(yùn)行在SystemServer進(jìn)程中
if (pid == 0) {
// 3.由于SystemServer進(jìn)程fork了Zygote進(jìn)程的地址空間,所以會(huì)得到Zygote進(jìn)程創(chuàng)建的Socket,
// 而這個(gè)Socket對(duì)于SystemServer進(jìn)程是無用的,因此,在此處關(guān)閉了該Socket。
zygoteServer.closeServerSocket();
// 4.啟動(dòng)SystemServer進(jìn)程
return handleSystemServerProcess(parsedArgs);
}
}
上面的代碼執(zhí)行過程會(huì)涉及到進(jìn)程的fork,在代碼1 處,Zygote.forkSystemServer()執(zhí)行的過程中會(huì)創(chuàng)建一個(gè)進(jìn)程,這個(gè)進(jìn)程就是systemServer進(jìn)程。那么fork完成后,此處的代碼會(huì)返回兩次,因?yàn)閒ork 會(huì)返回兩次,一次返回是執(zhí)行fork新創(chuàng)建的代碼,另外一次是zygote自己的代碼。第一次返回值如果是0 ,說明當(dāng)前運(yùn)行的是新的創(chuàng)建的進(jìn)程的代碼也就是systemServer進(jìn)程的代碼,第二次返回的值是一個(gè)大于0的值,說明當(dāng)前運(yùn)行的代碼是zygote進(jìn)程的代碼。因此就有了后面的if判斷也就是代碼2處,如果 pid 等于0 ,說明當(dāng)前進(jìn)程是運(yùn)行在systemServer進(jìn)程中。systemServer進(jìn)程是不需要zygoteServer的,于是就有了 closeServerSocket代碼的存在。然后,再執(zhí)行handleSystemServerProcess,運(yùn)行systemServer進(jìn)程。
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
if (parsedArgs.mInvokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
// 1.使用了systemServerClassPath和targetSdkVersion創(chuàng)建了一個(gè)PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
}
// 2.調(diào)用 ZygoteInit.zygoteInit 方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
以上代碼做了兩件事:1)基于sdk版本創(chuàng)建了一個(gè)ClassLoader;2)執(zhí)行zygoteInit方法。
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
// 1.進(jìn)入native方法
ZygoteInit.nativeZygoteInit();
// 2.獲取封裝了SystemServer的main函數(shù)的runnable
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
在zygoteInit函數(shù)中,首先是調(diào)用nativeZygoteinit函數(shù)來初始化進(jìn)程環(huán)境,然后再執(zhí)行applicationInit函數(shù)獲取封裝了SystemServer的main函數(shù)的Runnable。
2-1.ZygoteInit.nativeZygoteInit
在上一題《zygote進(jìn)程的啟動(dòng)流程》中我們知道有一個(gè)流程,那就是在zygote初始化的時(shí)候會(huì)注冊(cè)JNI,其中就有將nativeZygoteInit()方法和native函數(shù)com_android_internal_os_ZygoteInit_nativeZygoteInit()建立了映射關(guān)系。所以此時(shí)調(diào)用nativeZygoteInit()會(huì)調(diào)用到AndroidRuntime的下面的代碼。
static AndroidRuntime* gCurRuntime = NULL;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime是AndroidRuntime的指針,具體指向的是其子類AppRuntime,它在app_main.cpp中定義。代碼如下:
// frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
// 1.創(chuàng)建了一個(gè)ProcessState實(shí)例
sp<ProcessState> proc = ProcessState::self();
// 2.啟動(dòng)了一個(gè)Binder線程池
proc->startThreadPool();
}
在這個(gè)代碼中執(zhí)行的是進(jìn)程的初始化,首先在代碼1處,創(chuàng)建了一個(gè)進(jìn)程ProcessState,其中就會(huì)創(chuàng)建一個(gè)binder;然后在代碼2處啟動(dòng)了Binder線程池,為Binder線程的運(yùn)行提供了動(dòng)力。
到目前為止SystemServer進(jìn)程已經(jīng)創(chuàng)建完成,那么接下來就需要運(yùn)行systemServer進(jìn)程了,所以我們回到RuntimeInit.applicationInit函數(shù)中進(jìn)行分析。
2-2.RuntimeInit.applicationInit
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
// 1.通過反射得到了SystemServer類
cl = Class.forName(className, true, classLoader);
}
Method m;
try {
// 2.找到了 SystemServer中的main方法
m = cl.getMethod("main", new Class[] { String[].class });
}
// 3.將main()方法傳入MethodAndArgsCaller()方法中
return new MethodAndArgsCaller(m, argv);
}
以上代碼就是運(yùn)用反射,拿到systemServer的main 函數(shù),并且調(diào)用MethodAndArgsCaller,將main函數(shù)的調(diào)用封裝到一個(gè)Runnable中,方便后期的執(zhí)行。
static class MethodAndArgsCaller implements Runnable {
private final Method mMethod;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// 執(zhí)行SystemServer的main()方法
mMethod.invoke(null, new Object[] { mArgs });
}
}
}
這個(gè)Runnable的run方法是在ZygoteInit的main()方法中被執(zhí)行。代碼如下:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
try {
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run(); //1 執(zhí)行run
return;
}
}
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
如上面代碼1處,執(zhí)行run方法,這個(gè)時(shí)候就是執(zhí)行方法main(),所以,接下來我們看systemServer main函數(shù)的執(zhí)行。
3. SystemServer進(jìn)程執(zhí)行
// frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
main函數(shù)就一行代碼執(zhí)行SystemServer進(jìn)程的潤(rùn)函數(shù):
private void run() {
try {
Looper.prepareMainLooper();
// 1.加載動(dòng)態(tài)庫libandroid_servers.so
System.loadLibrary("android_servers");
// 2.創(chuàng)建SystemServerManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
// 3.初始化系統(tǒng)上下文
createSystemContext();
}
try {
// 3.使用SystemServiceManager啟動(dòng)引導(dǎo)服務(wù)
startBootstrapServices(t);
// 4.啟動(dòng)核心服務(wù)
startCoreServices(t);
// 5.啟動(dòng)其他服務(wù)
startOtherServices(t);
}
// Loop forever.
Looper.loop();
}
通過上面的代碼不難發(fā)現(xiàn),啟動(dòng)過程中,在大流程上systemServer和app進(jìn)程的啟動(dòng)很像,初始化了很多資源,也加載了很多資源,還創(chuàng)建了上下文,同時(shí)構(gòu)建了進(jìn)程的Looper 死循環(huán)確保進(jìn)程不會(huì)退出。當(dāng)然,在SystemServer中最重要的內(nèi)容還是通過代碼3,4,5啟動(dòng)了非常多的服務(wù),大概有90多個(gè)服務(wù),這些服務(wù)包括AMS,ATMS,WMS,PKMS,BMS等等一系列的服務(wù)。另外,在代碼2處創(chuàng)建了一個(gè)systemServiceManager對(duì)象,這個(gè)對(duì)象是用于在SystemServer進(jìn)程中管理90多個(gè)服務(wù)的啟動(dòng)的。
4.總結(jié)
SystemService進(jìn)程被創(chuàng)建后,主要的處理如下:
- 啟動(dòng)Binder線程池,這樣就可以與其他進(jìn)程進(jìn)行Binder跨進(jìn)程通信。
- SystemServer在啟動(dòng)過程中,先初始化一些系統(tǒng)變量,加載類庫,創(chuàng)建Context對(duì)象。
- 創(chuàng)建SystemServiceManager,它用來對(duì)系統(tǒng)服務(wù)進(jìn)行創(chuàng)建、啟動(dòng)和生命周期管理。
- 啟動(dòng)各種系統(tǒng)服務(wù):引導(dǎo)服務(wù)、核心服務(wù)、其他服務(wù),共90多種。應(yīng)用開發(fā)主要關(guān)注引導(dǎo)服務(wù)ActivityManagerService、PackageManagerService和其他服務(wù)WindowManagerService、InputManagerService即可。
- SystemServer在啟動(dòng)服務(wù)前,會(huì)嘗試與Zygote建立Socket通信,通信成功后才去啟動(dòng)服務(wù)。
- 啟動(dòng)的服務(wù)都單獨(dú)運(yùn)行在SystemServer的各自線程中,同屬于SystemServer進(jìn)程
最后
有需要面試題的朋友可以關(guān)注一下哇哇,以上都可以分享!??!