日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android5.0源码分析—— Zygote进程分析

發布時間:2025/3/15 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android5.0源码分析—— Zygote进程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1????? Zygote簡介

Android的應用程序一般都是由Java語言編寫而成的,這樣的應用程序需要運行在獨自的Dalvik虛擬機之上(當然,5.0好像默認了ART了)。但是,如果在每一個進程啟動時都在物理內存中創建和初始化一個Dalvik虛擬機,這無疑對系統的性能造成很大的影響。Zygote是Android系統中的一個非常重要的守護進程,所有其他應用程序的Dalvik虛擬機都是通過Zygote孵化出來的。通過這種方式,虛擬機的內存和框架層的資源被所有應用程序共享,從而提高了應用程序的啟動和運行速度。下圖為Android啟動的大致流程。


圖1. Android系統啟動的大致流程

?

2?????Zygote啟動流程分析

2.1???Init進程分析

拋開硬件層的有關內容后,Android的源頭應該為init進程。這個linux進程在操作系統的內核啟動的后期就被啟動了,并且之后所有的進程都是它的子孫進程。Init進程由main()開始,截取的部分代碼如下:

int main(int argc, char **argv)

{

?? ?……

????//創建并掛載了一些基本的系統文件

??? mkdir("/dev", 0755);

??? mkdir("/proc", 0755);

mkdir("/sys", 0755);

?

??? mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");

??? mkdir("/dev/pts", 0755);

??? mkdir("/dev/socket", 0755);

??? mount("devpts", "/dev/pts", "devpts", 0, NULL);

??? mount("proc", "/proc", "proc", 0, NULL);

??? mount("sysfs", "/sys", "sysfs", 0, NULL);

??? ……

??? //初始化了部分屬性

??? property_init();

?

??? ……

??? property_load_boot_defaults();

?

??? //加載了啟動配置文件,即init.rc文件

????init_parse_config_file("/init.rc");

??? //觸發Action

????action_for_each_trigger("early-init", action_add_queue_tail);

?

??? queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");

??? queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");

??? queue_builtin_action(keychord_init_action, "keychord_init");

??? queue_builtin_action(console_init_action, "console_init");

??? ……

??? queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");

????queue_builtin_action(property_service_init_action, "property_service_init");

??? queue_builtin_action(signal_init_action, "signal_init");

??? ……

??? for(;;) {

??????? int nr, i, timeout = -1;

?

????????execute_one_command();//執行當前Command中的一個命令,ActionService被啟動

????????restart_processes();?//重新啟動設置了重新啟動標志位的進程

????????//監聽來自屬性服務的事件

??????? if (!property_set_fd_init && get_property_set_fd() > 0) {

??????????? ufds[fd_count].fd = get_property_set_fd();

??????????? ufds[fd_count].events = POLLIN;

??????????? ufds[fd_count].revents = 0;

??????????? fd_count++;

??????????? property_set_fd_init = 1;

??????? }

????????//監控singal,如果子進程異常退出,內核將拋出SIGCHILD信號,此時將可以對進程進行處理

??????? //或是回收系統資源,或是重啟子進程

??????? if (!signal_fd_init && get_signal_fd() > 0) {

???? ???????ufds[fd_count].fd = get_signal_fd();

??????????? ufds[fd_count].events = POLLIN;

??????????? ufds[fd_count].revents = 0;

??????????? fd_count++;

??????????? signal_fd_init = 1;

??????? }

????????//監聽來自keychord設備的事件,這是個組合按鍵設備

??????? if (!keychord_fd_init && get_keychord_fd() > 0) {

??????????? ufds[fd_count].fd = get_keychord_fd();

??????????? ufds[fd_count].events = POLLIN;

??????????? ufds[fd_count].revents = 0;

??????????? fd_count++;

??????????? keychord_fd_init = 1;

??????? }

?

?????? ?……

????????nr = poll(ufds, fd_count, timeout);//利用poll監聽以上事件

??????? if (nr <= 0)

??????????? continue;

?

??????? for (i = 0; i < fd_count; i++) {

??????????? if (ufds[i].revents & POLLIN) {

??????????????? if (ufds[i].fd == get_property_set_fd())

??????????? ????????handle_property_set_fd();//處理屬性服務相關事件

??????????????? else if (ufds[i].fd == get_keychord_fd())

??????????????????? handle_keychord();//處理keychord事件

??????????????? else if (ufds[i].fd == get_signal_fd())

??????????????????? handle_signal();//處理singal事件

??????????? }

??????? }

??? }

??? return 0;

?

Zygote作為一個服務也被定義在了init.rc文件中,由init進程派生出來,配置代碼截取在如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote?--start-system-server

??? class main

????socket zygote stream 660 root system

??? onrestart write /sys/android_power/request_state wake

??? onrestart write /sys/power/state on

??? onrestart restart media

??? onrestart restart netd

由于Zygote是由java的服務進程,其啟動過程和其他在init.rc文件中定義的service啟動不太一樣。

2.2???App_main.cpp

通過配置信息可以定位Zygote的入口函數為app_main.cpp中的main,其代碼截取如下:

?

int main(int argc, char* const argv[])

{

……

//此類是AndroidRuntime的派生類

????AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

??? ……

??? while (i < argc) {//遍歷Zygote的配置參數

??????? const char* arg = argv[i++];

??????? if (strcmp(arg, "--zygote") == 0) {//為進程更換名字

??????????? zygote = true;

??????????? niceName = ZYGOTE_NICE_NAME;

??????? } else if (strcmp(arg, "--start-system-server") == 0) {//設置systemServertrue

??????????? startSystemServer = true;

??????? } else if (strcmp(arg, "--application") == 0) {//設置application啟動為true

??????????? application = true;

??????? } else if (strncmp(arg, "--nice-name=", 12) == 0) {

?????????? ……

??????? }

??? }

??? ……

??? if (zygote) {//如果配置參數中有參數顯示需要啟動Zygote,ZygoteInit啟動

????????runtime.start("com.android.internal.os.ZygoteInit", args);

??? } else if (className) {//否則RuntimeInit啟動

????????runtime.start("com.android.internal.os.RuntimeInit", args);

??? } else {

??????? ……

??? }

}

可見,app_main.cpp中的main()最為主要的是創建了一個AppRuntime變量,接著調用了它的start()成員函數。AppRuntime類繼承自AndroidRuntime類,它并沒有實現自己的start()方法,因此調用的是AndroidRuntime ::start()。而根據之前對App_main.cpp中main函數的分析,傳入到AndroidRuntime.start()的參數存在兩種情況:

1)runtime.start("com.android.internal.os.ZygoteInit",args)

2)runtime.start("com.android.internal.os.RuntimeInit",args)

因此可能存在兩種不同的啟動方式, “RuntimeInit”式啟動時序大致如下圖所示:


圖2.? “RuntimeInit”式啟動時序

由于在init.rc文件的Zygote服務已經配置了相關參數,因此這里只對ZygoteInit進行分析。AndroidRuntime.start()的主要作用是啟動Android系統運行時庫,代碼截取如下:

void AndroidRuntime::start(const char* className, const Vector<String8>& options)

{

??? ……//配置虛擬機的一些參數

??? JniInvocation jni_invocation;

??? jni_invocation.Init(NULL);

JNIEnv* env;

//開啟虛擬機

????if (startVm(&mJavaVM, &env) != 0) {

??????? return;

}

//這里實際上是調用了子類AppRuntimeonVmCreate(env)

onVmCreated(env);

//注冊Android JNI函數

????if (startReg(env) < 0) {

??????? ALOGE("Unable to register all android natives\n");

??????? return;

??? }

?

????//在開始調用main之前需要將參數轉化成java可識別的類型,并將其全部存入一個數組

??? jclass stringClass;

??? jobjectArray strArray;

??? jstring classNameStr;

?

??? stringClass = env->FindClass("java/lang/String");

??? assert(stringClass != NULL);

??? strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);

??? assert(strArray != NULL);

??? classNameStr = env->NewStringUTF(className);

??? assert(classNameStr != NULL);

??? env->SetObjectArrayElement(strArray, 0, classNameStr);

?

??? for (size_t i = 0; i < options.size(); ++i) {

??????? jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());

??????? assert(optionsStr != NULL);

??????? env->SetObjectArrayElement(strArray, i + 1, optionsStr);

??? }

char* slashClassName = toSlashClassName(className);

//找到需要啟動的java

??? jclass startClass = env->FindClass(slashClassName);

??? if (startClass == NULL) {

??????? ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);

} else {

??? ????//得到指定類中指定方法的ID,這里得到的是ZygoteInit.main()的方法ID

??????? jmethodID startMeth = env->GetStaticMethodID(startClass, "main",

??????????? "([Ljava/lang/String;)V");

??????? if (startMeth == NULL) {

??????????? ALOGE("JavaVM unable to find main() in '%s'\n", className);

??????? } else {

????????????//調用上面得到的方法ID和相關參數,即調用JavaZygoteInit.main();

????????????env->CallStaticVoidMethod(startClass, startMeth, strArray);

??? ????????……

??????? }

??? }

??? ……//回收資源關閉虛擬機等操作,這個函數除非進程退出,否則不會返回

}

AndroidRuntime.start()實際上主要做了3件事:1,startVM開啟虛擬機;2,startReg()注冊了JNI方法;3,調用Java方法。

2.3???ZygoteInit分析

ZygoteInit相關的類圖結構大致如下:

圖3.? ZygoteInit相關類圖結構

根據init.rc中Zygote的配置參數,AndroidRuntime.start()最終調用的是ZgoteInit.main()。其代碼截取如下:

public static void main(String argv[]) {

??????? try {

??????????? ……

????????????registerZygoteSocket(socketName);//初始化了server(zygote)的一個localsocket

??????????? EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,

???????? ???????SystemClock.uptimeMillis());

????????????preload();//加載了framwork.jarclass和資源到內存,這部分很占CPU

??????????? EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,

??????????????? SystemClock.uptimeMillis());

?

??????????? SamplingProfilerIntegration.writeZygoteSnapshot();

?

????????????gc();//由于后續需要fork出應用程序的進程,需要進行垃圾回收以確保應用程序的性能

?

??????????? Trace.setTracingEnabled(false);

?

??????????? if (startSystemServer) {

????????????????startSystemServer(abiList, socketName);//開啟System server服務

??????????? }

?

??????????? Log.i(TAG, "Accepting command socket connections");

????????????runSelectLoop(abiList);//開啟循環

?

??????????? closeServerSocket();

??????? } catch (MethodAndArgsCaller caller) {

????????????caller.run();//這里實際上是真正開啟了systemServer進程

??????? } catch (RuntimeException ex) {

??????????? Log.e(TAG, "Zygote died with exception", ex);

??????????? closeServerSocket();

??????????? throw ex;

??????? }

??? }

在ZygoteInit.main()中首先是調用了registerZygoteSocket(..)方法,該方法主要是為Zygote服務創建了一個localSocket。接著調用preload將class資源和系統的Resource加載到了內存中。之后利用gc()對垃圾進行回收。由于linux的寫時復制機制,在fork出應用程序之前對垃圾進行回收可以最小化子進程的垃圾內存。之后,ZygoteInit.main()分別調用了startSystemServer()、runSelectLoop()方法。startSystemServer()開啟了SystemServer,此進程是Zygote孵化出來的第一個java進程。而runSelectLoop()進入select的循環,用來響應其他應用程序(AMS)的請求。

2.4???Zygote啟動SystemServer服務簡要分析

SystemServer進程是Zygote 孵化出來的第一個進程,此進程有很多的系統進程,提供了所有核心的系統服務。與孵化其他進程不同,Zygote單獨對SystemServer進程做了孵化工作。ZygoteInit.main()中調用了startSystemServer(),代碼如下:

private static boolean startSystemServer(String abiList, String socketName)

??????????? throws MethodAndArgsCaller, RuntimeException {

??????? long capabilities = posixCapabilitiesAsBits(

??????????? OsConstants.CAP_BLOCK_SUSPEND,

??????????? OsConstants.CAP_KILL,

??????????? OsConstants.CAP_NET_ADMIN,

??????????? OsConstants.CAP_NET_BIND_SERVICE,

??????????? OsConstants.CAP_NET_BROADCAST,

??????????? OsConstants.CAP_NET_RAW,

??????????? OsConstants.CAP_SYS_MODULE,

??????????? OsConstants.CAP_SYS_NICE,

??????????? OsConstants.CAP_SYS_RESOURCE,

??????????? OsConstants.CAP_SYS_TIME,

??????????? OsConstants.CAP_SYS_TTY_CONFIG

??????? );

????????//SystemServer的啟動參數設置

??????? 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",

??????? };

??????? ZygoteConnection.Arguments parsedArgs = null;

?

??????? int pid;

?

??????? try {

??????????? parsedArgs = new ZygoteConnection.Arguments(args);

??????????? ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);

??????????? ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

?

????????????//Zygote發送fork請求

????????????pid = Zygote.forkSystemServer(

????????????????????parsedArgs.uid, parsedArgs.gid,

????????????????????parsedArgs.gids,

????????????????????parsedArgs.debugFlags,

????????????????????null,

????????????????????parsedArgs.permittedCapabilities,

????????????????????parsedArgs.effectiveCapabilities);

??????? } catch (IllegalArgumentException ex) {

??????????? throw new RuntimeException(ex);

????? ??}

?

????????//以下代碼僅對子進程SystemServer有效

??????? if (pid == 0) {

??????????? if (hasSecondZygote(abiList)) {

??????????????? waitForSecondaryZygote(socketName);

??????????? }

????????????handleSystemServerProcess(parsedArgs);

??????? }

??????? return true;

??? }

進入handleSystemServerProcess(parsedArgs),從代碼中可以看到Zygote根據請求創建了SystemServer進程,這個進程運行handleSystemServerProcess()。此函數對部分參數做了處理,并將剩余的參數傳遞給了SystemServer。

??? private static void handleSystemServerProcess(

??????????? ZygoteConnection.Arguments parsedArgs)

??????????? throws ZygoteInit.MethodAndArgsCaller {

?

??????? closeServerSocket();

??????? //設置默認權限

????????Os.umask(S_IRWXG | S_IRWXO);

?

??????? if (parsedArgs.niceName != null) {

??????????? Process.setArgV0(parsedArgs.niceName);

??????? }

?

??????? final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");

??????? if (systemServerClasspath != null) {

??????????? performSystemServerDexOpt(systemServerClasspath);

??????? }

?

??????? if (parsedArgs.invokeWith != null) {

??????????? String[] args = parsedArgs.remainingArgs;

??????????? if (systemServerClasspath != null) {

??????????????? String[] amendedArgs = new String[args.length + 2];

??????????????? amendedArgs[0] = "-cp";

??????????????? amendedArgs[1] = systemServerClasspath;

??????????????? System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);

??????????? }

??????????? //一種可能的啟動方式

??????????? WrapperInit.execApplication(parsedArgs.invokeWith,

??????????????????? parsedArgs.niceName, parsedArgs.targetSdkVersion,

??????????????????? null, args);

??????? } else {//更為常見的啟動方式

??????????? ClassLoader cl = null;

??????????? if (systemServerClasspath != null) {

??????????????? cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());

??????????????? Thread.currentThread().setContextClassLoader(cl);

??????????? }

??????????? //將余下的參數傳遞給RuntimeInit.zygoteInit處理

????????????RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);

??????? }

??????? //永遠不會執行到這里

??? }

進入RuntimeInit.zygoteInit()

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

??????????? throws ZygoteInit.MethodAndArgsCaller {

??????? if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

??????? //重定向log

??????? redirectLogStreams();

???????? //初始化運行環境

??????? commonInit();

??????? //啟動binder線程池

????????nativeZygoteInit();

??????? //調用應用程序的入口函數

????????applicationInit(targetSdkVersion, argv, classLoader);

??? }

進入applicationInit()

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller{

??????? nativeSetExitWithoutCleanup(true);

??????? ……

????????invokeStaticMain(args.startClass, args.startArgs, classLoader);

??? }

進入invokeStaticMain ()

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)

??????????? throws ZygoteInit.MethodAndArgsCaller {

??????? //解析類名

??????? Class<?> cl;

??????? try {

????????????cl = Class.forName(className, true, classLoader);

??????? } catch (ClassNotFoundException ex) {

??????????? throw new RuntimeException(

??????????????????? "Missing class when invoking static main " + className,

??????????????????? ex);

?????? ?}

??????? //解析main方法

??????? Method m;

??????? try {

????????????m = cl.getMethod("main", new Class[] { String[].class });

??????? } catch (NoSuchMethodException ex) {

??????????? throw new RuntimeException(

??????????????????? "Missing static main on " + className, ex);

??????? } catch (SecurityException ex) {

??????????? throw new RuntimeException(

??????????????????? "Problem getting static main on " + className, ex);

??????? }

?

??????? int modifiers = m.getModifiers();

??????? if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {

??????????? throw new RuntimeException(

??????????????????? "Main method is not public and static on " + className);

??????? }

??????? //這里并沒有直接去調用SystemServer.main()而是拋出了一個異常,這個異常將在//ZygoteInit.main()中被捕捉

? ??????throw new ZygoteInit.MethodAndArgsCaller(m, argv);

??? }

這里非常奇怪,invokeStaticMain并沒有像我們想象的那樣直接去調用SystemServer類的有關代碼,它只是獲取了SystemServer.main方法體和有關參數,并將其封裝在一個MethodAndArgsCaller異常中,這個異常將在ZygoteInit.main中被捕捉。具體可以查看之前的代碼。先查看一下這個異常類的設計,進入MethodAndArgsCaller類查看代碼。

public static class MethodAndArgsCaller extends Exception

??????????? implements Runnable {

????????//調用方法體

????????private final Method mMethod;

?

????????//調用方法所需要的參數

????????private final String[] mArgs;

?

??????? public MethodAndArgsCaller(Method method, String[] args) {

??????????? mMethod = method;

??????????? mArgs = args;

??????? }

?

??????? public void run() {

??????????? try {

????????????????//最終還是調用了main()方法

????????????????mMethod.invoke(null, new Object[] { mArgs });

??????????? } catch (IllegalAccessException ex) {

??????????????? throw new RuntimeException(ex);

??????????? } catch (InvocationTargetException ex) {

??????????????? Throwable cause = ex.getCause();

??????????????? if (cause instanceof RuntimeException) {

??????????????????? throw (RuntimeException) cause;

??????????????? } else if (cause instanceof Error) {

??????????????????? throw (Error) cause;

??????????????? }

??????????????? throw new RuntimeException(ex);

??????????? }

??????? }

??? }

}

拋出MethodAndArgsCaller異常分析:MethodAndArgsCaller異常是在startSystemSerer()中拋出的,從單個文件的代碼來看,程序的執行流跳過runSelectLoop(..)。而runSelectLoop()是Zygote的服務的一個非常重要的方法。這顯然不合理??紤]到startSystemServer中開啟了名字為SystemServer的進程(此時,這個子進程程序流還未流入SystemServer.main()),拋出這個異常MethodAndArgsCaller的實際上是handleSystemServerProcess()的,即SystemServer進程,而父進程Zygote并未受影響。因此跳過runSelectLoop(..)是合理的。通過這樣的方式,可以擺脫在啟動初期時設置的堆棧楨。這些應該都和linux的fork機制有關。

以上SystemServer的啟動流程大致時序如下圖所示。

圖4.? SystemServer啟動大致時序

2.5???runSelectLoop()分析

在分析runSelectLoop之前,需要對應用程序的啟動流程作一下簡要的分析。應用程序的主入口是在ActivityThread的main函數,activity的startActivity最終是在ActivityManagerService中執行的。

首先調用的是ActivityManagerService.startProcessLocked()方法,這個方法有多個重載方法,但是都會調用Process.startViaZygote(),這個方法內部實際上是開啟一個localSocket并連接Zygote進程(此時的Zygote正處于runSelectLoop之中監聽事件)。建立連接之后首先是將參數通過localsocket對應的writer對象發送了所要啟動APP的相關參數給Zygote,并等待localsocke對應的inputStream返回一個int型的pid。以及另一個boolean型的參數usingWrapper。

圖5.? 啟動應用程序大致時序

之前已經描述,Zygote在建立ServerSystem服務之后一直處于runSelectLoop循環中,等待AMS的fork請求,runSelectLoop代碼截取如下:

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {

??????? ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();

??????? ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

??????? FileDescriptor[] fdArray = new FileDescriptor[4];

?

??????? fds.add(sServerSocket.getFileDescriptor());

??????? peers.add(null);

?

??????? int loopCount = GC_LOOP_COUNT;

??????? while (true) {

??????????? int index;

??????????? if (loopCount <= 0) {

??????????????? gc();//在比較空閑的時候執行gc

??????????????? loopCount = GC_LOOP_COUNT;

??????????? } else {

??????????????? loopCount--;

??????????? }

??????????? try {

??????????????? fdArray = fds.toArray(fdArray);

????????????????//這是一個Native方法,其方法內部調用了Select系統函數等待客戶端連接請求

????????????????index = selectReadable(fdArray);//注意這里的返回值和select()的返回值是不//同的概念,這里Index是活動fd的索引

??????????? } catch (IOException ex) {

??????????????? throw new RuntimeException("Error in select()", ex);

??????????? }

??????????? if (index < 0) {

??????????????? throw new RuntimeException("Error in select()");

??????????? } else if (index == 0) {//有連接進入,放入監聽fd隊列

????????????????ZygoteConnection newPeer = acceptCommandPeer(abiList);

????????????????peers.add(newPeer);

??????????????? fds.add(newPeer.getFileDescriptor());

??????????? } else {//有請求

??????????????? boolean done;

????????????????done = peers.get(index).runOnce();//處理請求

?

??????????????? if (done) {

??????????????????? peers.remove(index);

??????????????????? fds.remove(index);

??????????????? }

??????????? }

??????? }

??? }

進入runOnce()

??? boolean runOnce()?throws ZygoteInit.MethodAndArgsCaller?{

?

??????? String args[];

??????? Arguments parsedArgs = null;

??????? FileDescriptor[] descriptors;

?

??????? long startTime = SystemClock.elapsedRealtime();

?

??????? try {

????????????args = readArgumentList();//讀取傳遞進來的請求參數

??????????? descriptors = mSocket.getAncillaryFileDescriptors();

??????? }……

?????????? ……//fork出應用進程

????????????pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,

????????????????????parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,

????????????????????parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,

????????????????????parsedArgs.appDataDir);

?????????? ……

??????? try {

?????? ?????if (pid == 0) {

????????????????//?子進程中

??????????????? IoUtils.closeQuietly(serverPipeFd);

??????????????? serverPipeFd = null;

????????????????handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

??????????????? return true;

??????????? } else {

????????????????//?父進程中

??????????????? IoUtils.closeQuietly(childPipeFd);

??????????????? childPipeFd = null;

????????????????//發送pidusingWrapperAMS

????????????????return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);

??????????? }

??????? } finally {

??????????? IoUtils.closeQuietly(childPipeFd);

??????????? IoUtils.closeQuietly(serverPipeFd);

??????? }

??? }

進入handleChildProc()

??? private void handleChildProc(Arguments parsedArgs,

??????????? FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)

??????????? throws ZygoteInit.MethodAndArgsCaller {

?

??????? closeSocket();

??????? ZygoteInit.closeServerSocket();

???????? ……

??????? if (parsedArgs.niceName != null) {//設置進程名字

??????????? Process.setArgV0(parsedArgs.niceName);

??????? }

????????//參數中配置了RuntimeInit,這里為true

??????? if (parsedArgs.runtimeInit) {

??????????? if (parsedArgs.invokeWith != null) {//Android中另一種可能的啟動方式

??????????????? WrapperInit.execApplication(parsedArgs.invokeWith,

??????????????????????? parsedArgs.niceName, parsedArgs.targetSdkVersion,

??????????????????????? pipeFd, parsedArgs.remainingArgs);

??????????? } else {//程序最終會走到這里

????????????????RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,

????????????????????????parsedArgs.remainingArgs, null);

??????????? }

??????? } else {

?????????? ……

??????? }

??? }

可看到,handleChildProc最終調用RuntimeInit.ZygoteInit()。這個方法在分析SystemServer啟動過程時已經分析過了,它依次調用了redirectLogStreams()、commonInit()、zygoteInitNative()? applicationInit()并最終調用了invokeStaticMain()拋出異常,在catch塊中運行指定類的main函數。


?

3????????分析與總結

本文主要分析了Android5.0中Zygote的啟動,以及Zygote孵化SystemServer進程和普通應用進程的過程。從以上的分析可以得知,Android充分利用了Linux的一些特性,在保證了內存被盡可能地共享的同時,又保證了系統的性能和速度


原文地址: http://blog.csdn.net/a34140974/article/details/49783781

總結

以上是生活随笔為你收集整理的Android5.0源码分析—— Zygote进程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。