在android中,應(yīng)用程序的入口是ActivityThead中的main函數(shù),那么之后系統(tǒng)是怎樣為應(yīng)用程序創(chuàng)建進(jìn)程的呢?SystemService又是怎樣創(chuàng)建的?答案是:zygote
zygote翻譯成中文是受精卵的意思,名字比較奇怪、但是很有意思。在android中,大部分的應(yīng)用程序進(jìn)程都是由zygote來創(chuàng)建的,為什么用大部分,因?yàn)檫€有一些進(jìn)程比如系統(tǒng)引導(dǎo)進(jìn)程、init進(jìn)程等不是有zygote創(chuàng)建的。相反,zygote還是在init進(jìn)程之后才被創(chuàng)建的。在android中提到zygote,主要兩塊,一個(gè)是C/C++編寫的zygote,主要用來為應(yīng)用和SystemService fork進(jìn)程的。一個(gè)是java編寫的zygote接口,負(fù)責(zé)為應(yīng)用和service調(diào)用C/C++ zygote的接口執(zhí)行fork,從而創(chuàng)建VM進(jìn)程。說明:在android中,service主要有NativeService和SystemService。SystemService主要是指系統(tǒng)中service,比如,InputMethodService、ActivityManagerService等。
zygote在android中主要有兩個(gè)作用:
- 建立運(yùn)行時(shí)環(huán)境并啟動虛擬機(jī),執(zhí)行com.android.internal.os.ZygoteInit的main函數(shù),從而fork SystemService
- runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);
- 為應(yīng)用程序創(chuàng)建DVM進(jìn)程。
啟動SystemServer:
我們來看看zygote是怎樣創(chuàng)建SystemService進(jìn)程的。在../base/cmds/app_process/app_main.cpp的主函數(shù)中,有這樣一段代碼,它執(zhí)行了
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer); //runtime繼承自AndroidRuntime
也就是說,在主函數(shù)中,初始化了運(yùn)行時(shí)環(huán)境,并且建立虛擬機(jī),然后運(yùn)行再com.android.internal.os.ZygoteInit的main函數(shù)
再來看看com.android.internal.os.ZygoteInit的main中都做了哪些事情。在看ZygoteInit之前,有必要先來看下相關(guān)的類,類圖如下:

在ZygoteInit的main函數(shù)中,主要執(zhí)行了:
- registerZygoteSocket();//登記Listen端口
- startSystemServer();//啟動SystemServer
startSystemServer()調(diào)用Zygote的native方法 forkSystemServer(); 到這里,java端的Zygote的準(zhǔn)備工作就結(jié)束了,接下來就交給C/C++端的Zygote來執(zhí)行fork任務(wù)了。來看下代碼:
在 ../dalvik/vm/native/dalvik_system_Zygote.c 中
- static void Dalvik_dalvik_system_Zygote_forkSystemServer(
- const u4* args, JValue* pResult)
- {
- pid_t pid;
- /*調(diào)用forkAndSpecializeCommon,執(zhí)行fork */
- pid = forkAndSpecializeCommon(args, true);
- /* 檢查fork后返回的進(jìn)程pid */
- if (pid > 0) {
- int status;
- LOGI("System server process %d has been created", pid);
- gDvm.systemServerPid = pid;
- if (waitpid(pid, &status, WNOHANG) == pid) {
- LOGE("System server process %d has died. Restarting Zygote!", pid);
- kill(getpid(), SIGKILL);
- }
- }
- RETURN_INT(pid);
- }
在這個(gè)里面的fork進(jìn)程主要是使用linux的fork進(jìn)程。
經(jīng)過這樣的過程SystemServer進(jìn)程就創(chuàng)建起來了。android中的所有服務(wù)循環(huán)框架都是建立咋SystemServer上,接下來在SystemServer上,就可以建立所有系統(tǒng)服務(wù)??蓞⒖矗篠ystemServer.main();
系統(tǒng)服務(wù)啟動后會調(diào)用ActivityManagerService的systemReady方法,并最終啟動HomeActivity。
啟動應(yīng)用進(jìn)程:
我們在上一篇介紹ActivityThread和ActivityManagerService時(shí)已經(jīng)講過,程序的主入口是在ActivityThread的main函數(shù),activity的startActivity最終是在ActivityManagerService中執(zhí)行的,那么應(yīng)用程序的進(jìn)程是怎么創(chuàng)建的?看下類圖:

我們再來看看ActivityManagerService中的startProcessLocked方法。
- int pid = Process.start("android.app.ActivityThread",
- mSimpleProcessManagement ? app.processName : null, uid, uid,
- gids, debugFlags, null);
通過Process的start方法來創(chuàng)建進(jìn)程。
- / **
- *通過Zygote進(jìn)程來創(chuàng)建新的vm進(jìn)程
- */
-
- public static final int start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags,String[] zygoteArgs)
- {
- if (supportsProcesses()) {
- try {
- return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, zygoteArgs); //argsForZygote.add("--runtime-init")初始化運(yùn)行環(huán)境
- } catch (ZygoteStartFailedEx ex) {
- Log.e(LOG_TAG,
- "Starting VM process through Zygote failed");
- throw new RuntimeException(
- "Starting VM process through Zygote failed", ex);
- }
-
- } else {
-
- // Running in single-process mode
- Runnable runnable = new Runnable() {
- public void run() {
- Process.invokeStaticMain(processClass);
- }
- };
- // Thread constructors must not be called with null names (see spec).
- if (niceName != null) {
- new Thread(runnable, niceName).start();
- } else {
- new Thread(runnable).start();
- }
- return 0;
- }
- }
在ZygoteConnection中獲取套接字連接,并解析啟動參數(shù)。來看下runOnce方法:
從LocalSocket. mSocket中解析參數(shù)
- try {
- args = readArgumentList();
- descriptors = mSocket.getAncillaryFileDescriptors();
- } catch (IOException ex) {
- Log.w(TAG, "IOException on command socket " + ex.getMessage());
- closeSocket();
- return true;
- }
- 調(diào)用Zygote的native方法forkAndSpecialize,執(zhí)行進(jìn)程的創(chuàng)建工作。本地方法的實(shí)現(xiàn)也是在 ../dalvik/vm/native/dalvik_system_Zygote.c 中,底層調(diào)用linux的fork。
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
-
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
這樣應(yīng)用程序的進(jìn)程就創(chuàng)建起來了。從ActivityManagerService開始的時(shí)序圖如下:

總結(jié):
- 在android中SystemService的啟動是在Zygote進(jìn)程創(chuàng)建好后進(jìn)行的,并且由Zygote進(jìn)程建立好DVM運(yùn)行環(huán)境,加載ZygoteInit的main函數(shù),最終調(diào)用Zygote的本地方法forkSystemServer,并執(zhí)行l(wèi)inux的fork方法創(chuàng)建SystemServer進(jìn)程。
- 應(yīng)用程序的進(jìn)程也是由Zygote創(chuàng)建的,在ActivityManagerService中的startProcessLocked中調(diào)用了Process.start()方法。并通過連接調(diào)用Zygote的native方法forkAndSpecialize,執(zhí)行fork任務(wù)。
- 應(yīng)用進(jìn)程和服務(wù)進(jìn)程位于不同的進(jìn)程中,他們之間是通過IPC進(jìn)行數(shù)據(jù)傳遞的。接下來一篇會介紹在android中的進(jìn)程間通信機(jī)制:Binder