?原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696
?
Android應用程序框架層創(chuàng)建的應用程序進程具有兩個特點,一是進程的入口函數(shù)是ActivityThread.main,二是進程天然支持Binder進程間通信機制;這兩個特點都是在進程的初始化過程中實現(xiàn)的,本文將詳細分析Android應用程序進程創(chuàng)建過程中是如何實現(xiàn)這兩個特點的。
?? ? ???Android應用程序框架層創(chuàng)建的應用程序進程的入口函數(shù)是ActivityThread.main比較好理解,即進程創(chuàng)建完成之后,Android應用程序框架層就會在這個進程中將ActivityThread類加載進來,然后執(zhí)行它的main函數(shù),這個main函數(shù)就是進程執(zhí)行消息循環(huán)的地方了。Android應用程序框架層創(chuàng)建的應用程序進程天然支持Binder進程間通信機制這個特點應該怎么樣理解呢?前面我們在學習Android系統(tǒng)的Binder進程間通信機制時說到,它具有四個組件,分別是驅(qū)動程序、守護進程、Client以及Server,其中Server組件在初始化時必須進入一個循環(huán)中不斷地與Binder驅(qū)動程序進行到交互,以便獲得Client組件發(fā)送的請求,具體可參考Android系統(tǒng)進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析一文,但是,當我們在Android應用程序中實現(xiàn)Server組件的時候,我們并沒有讓進程進入一個循環(huán)中去等待Client組件的請求,然而,當Client組件得到這個Server組件的遠程接口時,卻可以順利地和Server組件進行進程間通信,這就是因為Android應用程序進程在創(chuàng)建的時候就已經(jīng)啟動了一個線程池來支持Server組件和Binder驅(qū)動程序之間的交互了,這樣,極大地方便了在Android應用程序中創(chuàng)建Server組件。
?? ? ? ?在Android應用程序框架層中,是由ActivityManagerService組件負責為Android應用程序創(chuàng)建新的進程的,它本來也是運行在一個獨立的進程之中,不過這個進程是在系統(tǒng)啟動的過程中創(chuàng)建的。ActivityManagerService組件一般會在什么情況下會為應用程序創(chuàng)建一個新的進程呢?當系統(tǒng)決定要在一個新的進程中啟動一個Activity或者Service時,它就會創(chuàng)建一個新的進程了,然后在這個新的進程中啟動這個Activity或者Service,具體可以參考Android系統(tǒng)在新進程中啟動自定義服務過程(startService)的原理分析、Android應用程序啟動過程源代碼分析和Android應用程序在新的進程中啟動新的Activity的方法和過程分析這三篇文章。
?? ? ? ?ActivityManagerService啟動新的進程是從其成員函數(shù)startProcessLocked開始的,在深入分析這個過程之前,我們先來看一下進程創(chuàng)建過程的序列圖,然后再詳細分析每一個步驟。
?? ? ??點擊查看大圖
?? ? ? ?Step 1. ActivityManagerService.startProcessLocked
?? ? ? ?這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
?
[java]?view plaincopy
public?final?class?ActivityManagerService?extends?ActivityManagerNative????????????implements?Watchdog.Monitor,?BatteryStatsImpl.BatteryCallback?{????????????......????????????private?final?void?startProcessLocked(ProcessRecord?app,????????????????????String?hostingType,?String?hostingNameStr)?{????????????????......????????????????try?{????????????????int?uid?=?app.info.uid;????????????????int[]?gids?=?null;????????????????try?{????????????????????gids?=?mContext.getPackageManager().getPackageGids(????????????????????????app.info.packageName);????????????????}?catch?(PackageManager.NameNotFoundException?e)?{????????????????????......????????????????}????????????????????????????????......????????????????????int?debugFlags?=?0;????????????????????????????????......????????????????????????????????int?pid?=?Process.start("android.app.ActivityThread",????????????????????mSimpleProcessManagement???app.processName?:?null,?uid,?uid,????????????????????gids,?debugFlags,?null);????????????????????????????????......????????????????}?catch?(RuntimeException?e)?{????????????????????????????????......????????????????}????????}????????????......????????}???? ?? ? ? ?它調(diào)用了Process.start函數(shù)開始為應用程序創(chuàng)建新的進程,注意,它傳入一個第一個參數(shù)為"android.app.ActivityThread",這就是進程初始化時要加載的Java類了,把這個類加載到進程之后,就會把它里面的靜態(tài)成員函數(shù)main作為進程的入口點,后面我們會看到。
?
?? ? ? ?Step 2. Process.start?
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中:
?
[java]?view plaincopy
public?class?Process?{??????......????????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);??????????????}?catch?(ZygoteStartFailedEx?ex)?{??????????????????......??????????????}??????????}?else?{??????????????......????????????????return?0;??????????}??????}????????......??}?? ?? ? ? 這里的supportsProcesses函數(shù)返回值為true,它是一個Native函數(shù),實現(xiàn)在frameworks/base/core/jni/android_util_Process.cpp文件中:
?
?
[cpp]?view plaincopy
jboolean?android_os_Process_supportsProcesses(JNIEnv*?env,?jobject?clazz)??{??????return?ProcessState::self()->supportsProcesses();??}?? ?
?? ? ? ProcessState::supportsProcesses函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
?
[cpp]?view plaincopy
bool?ProcessState::supportsProcesses()?const??{??????return?mDriverFD?>=?0;??}?? ?? ? ? 這里的mDriverFD是設備文件/dev/binder的打開描述符,如果成功打開了這個設備文件,那么它的值就會大于等于0,因此,它的返回值為true。
?
?? ? ? 回到Process.start函數(shù)中,它調(diào)用startViaZygote函數(shù)進一步操作。
?? ? ? Step 3.?Process.startViaZygote
?? ? ??這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中:
?
[java]?view plaincopy
public?class?Process?{??????......????????private?static?int?startViaZygote(final?String?processClass,??????????????final?String?niceName,??????????????final?int?uid,?final?int?gid,??????????????final?int[]?gids,??????????????int?debugFlags,??????????????String[]?extraArgs)??????????????throws?ZygoteStartFailedEx?{??????????int?pid;????????????synchronized(Process.class)?{??????????????ArrayList<String>?argsForZygote?=?new?ArrayList<String>();????????????????????????????????????????argsForZygote.add("--runtime-init");??????????????argsForZygote.add("--setuid="?+?uid);??????????????argsForZygote.add("--setgid="?+?gid);??????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_SAFEMODE)?!=?0)?{??????????????????argsForZygote.add("--enable-safemode");??????????????}??????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_DEBUGGER)?!=?0)?{??????????????????argsForZygote.add("--enable-debugger");??????????????}??????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_CHECKJNI)?!=?0)?{??????????????????argsForZygote.add("--enable-checkjni");??????????????}??????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_ASSERT)?!=?0)?{??????????????????argsForZygote.add("--enable-assert");??????????????}??????????????????????????????????????????????????????if?(gids?!=?null?&&?gids.length?>?0)?{??????????????????StringBuilder?sb?=?new?StringBuilder();??????????????????sb.append("--setgroups=");????????????????????int?sz?=?gids.length;??????????????????for?(int?i?=?0;?i?<?sz;?i++)?{??????????????????????if?(i?!=?0)?{??????????????????????????sb.append(',');??????????????????????}??????????????????????sb.append(gids[i]);??????????????????}????????????????????argsForZygote.add(sb.toString());??????????????}????????????????if?(niceName?!=?null)?{??????????????????argsForZygote.add("--nice-name="?+?niceName);??????????????}????????????????argsForZygote.add(processClass);????????????????if?(extraArgs?!=?null)?{??????????????????for?(String?arg?:?extraArgs)?{??????????????????????argsForZygote.add(arg);??????????????????}??????????????}????????????????pid?=?zygoteSendArgsAndGetPid(argsForZygote);??????????}??????}????????......??}?? ?? ? ? ?這個函數(shù)將創(chuàng)建進程的參數(shù)放到argsForZygote列表中去,如參數(shù)"--runtime-init"表示要為新創(chuàng)建的進程初始化運行時庫,然后調(diào)用zygoteSendAndGetPid函數(shù)進一步操作。
?
?? ? ? ?Step 4. Process.zygoteSendAndGetPid
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中:
?
[java]?view plaincopy
public?class?Process?{??????......????????private?static?int?zygoteSendArgsAndGetPid(ArrayList<String>?args)??????????????throws?ZygoteStartFailedEx?{??????????int?pid;????????????openZygoteSocketIfNeeded();????????????try?{????????????????????????????sZygoteWriter.write(Integer.toString(args.size()));??????????????sZygoteWriter.newLine();????????????????int?sz?=?args.size();??????????????for?(int?i?=?0;?i?<?sz;?i++)?{??????????????????String?arg?=?args.get(i);??????????????????if?(arg.indexOf('\n')?>=?0)?{??????????????????????throw?new?ZygoteStartFailedEx(??????????????????????????"embedded?newlines?not?allowed");??????????????????}??????????????????sZygoteWriter.write(arg);??????????????????sZygoteWriter.newLine();??????????????}????????????????sZygoteWriter.flush();????????????????????????????pid?=?sZygoteInputStream.readInt();????????????????if?(pid?<?0)?{??????????????????throw?new?ZygoteStartFailedEx("fork()?failed");??????????????}??????????}?catch?(IOException?ex)?{??????????????......??????????}????????????return?pid;??????}????????......??}?? ?? ? ? ? 這里的sZygoteWriter是一個Socket寫入流,是由openZygoteSocketIfNeeded函數(shù)打開的:
?
?
[java]?view plaincopy
public?class?Process?{??????......????????????private?static?void?openZygoteSocketIfNeeded()??????????????throws?ZygoteStartFailedEx?{????????????int?retryCount;????????????if?(sPreviousZygoteOpenFailed)?{??????????????????????????retryCount?=?0;??????????}?else?{??????????????retryCount?=?10;??????????}????????????????????????for?(int?retry?=?0??????????????;?(sZygoteSocket?==?null)?&&?(retry?<?(retryCount?+?1))??????????????;?retry++?)?{????????????????????if?(retry?>?0)?{??????????????????????try?{??????????????????????????Log.i("Zygote",?"Zygote?not?up?yet,?sleeping...");??????????????????????????Thread.sleep(ZYGOTE_RETRY_MILLIS);??????????????????????}?catch?(InterruptedException?ex)?{??????????????????????????????????????????????}??????????????????}????????????????????try?{??????????????????????sZygoteSocket?=?new?LocalSocket();??????????????????????sZygoteSocket.connect(new?LocalSocketAddress(ZYGOTE_SOCKET,??????????????????????????LocalSocketAddress.Namespace.RESERVED));????????????????????????sZygoteInputStream??????????????????????????=?new?DataInputStream(sZygoteSocket.getInputStream());????????????????????????sZygoteWriter?=??????????????????????????new?BufferedWriter(??????????????????????????new?OutputStreamWriter(??????????????????????????sZygoteSocket.getOutputStream()),??????????????????????????256);????????????????????????Log.i("Zygote",?"Process:?zygote?socket?opened");????????????????????????sPreviousZygoteOpenFailed?=?false;??????????????????????break;??????????????????}?catch?(IOException?ex)?{??????????????????????......??????????????????}??????????}????????????......??????}????????......??}?? ?? ? ? ?這個Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit類在runSelectLoopMode函數(shù)偵聽的。
?? ? ? ?Step 5.?ZygoteInit.runSelectLoopMode
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
?
?
[java]?view plaincopy
public?class?ZygoteInit?{??????......????????????private?static?void?runSelectLoopMode()?throws?MethodAndArgsCaller?{??????????ArrayList<FileDescriptor>?fds?=?new?ArrayList();??????????ArrayList<ZygoteConnection>?peers?=?new?ArrayList();??????????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();??????????????????loopCount?=?GC_LOOP_COUNT;??????????????}?else?{??????????????????loopCount--;??????????????}??????????????????try?{??????????????????fdArray?=?fds.toArray(fdArray);??????????????????index?=?selectReadable(fdArray);??????????????}?catch?(IOException?ex)?{??????????????????throw?new?RuntimeException("Error?in?select()",?ex);??????????????}????????????????if?(index?<?0)?{??????????????????throw?new?RuntimeException("Error?in?select()");??????????????}?else?if?(index?==?0)?{??????????????????ZygoteConnection?newPeer?=?acceptCommandPeer();??????????????????peers.add(newPeer);??????????????????fds.add(newPeer.getFileDesciptor());??????????????}?else?{??????????????????boolean?done;??????????????????done?=?peers.get(index).runOnce();????????????????????if?(done)?{??????????????????????peers.remove(index);??????????????????????fds.remove(index);??????????????????}??????????????}??????????}??????}????????......??}?? ?? ? ? ?當Step 4將數(shù)據(jù)通過Socket接口發(fā)送出去后,就會下面這個語句:
?
?
[java]?view plaincopy
done?=?peers.get(index).runOnce();?? ?? ? ? ?這里從peers.get(index)得到的是一個ZygoteConnection對象,表示一個Socket連接,因此,接下來就是調(diào)用ZygoteConnection.runOnce函數(shù)進一步處理了。
?
?? ? ? ?Step 6.?ZygoteConnection.runOnce
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
?
[java]?view plaincopy
class?ZygoteConnection?{??????......????????boolean?runOnce()?throws?ZygoteInit.MethodAndArgsCaller?{??????????String?args[];??????????Arguments?parsedArgs?=?null;??????????FileDescriptor[]?descriptors;????????????try?{??????????????args?=?readArgumentList();??????????????descriptors?=?mSocket.getAncillaryFileDescriptors();??????????}?catch?(IOException?ex)?{??????????????......??????????????return?true;??????????}????????????......????????????????????PrintStream?newStderr?=?null;????????????if?(descriptors?!=?null?&&?descriptors.length?>=?3)?{??????????????newStderr?=?new?PrintStream(??????????????????new?FileOutputStream(descriptors[2]));??????????}????????????int?pid;????????????????????try?{??????????????parsedArgs?=?new?Arguments(args);????????????????applyUidSecurityPolicy(parsedArgs,?peer);??????????????applyDebuggerSecurityPolicy(parsedArgs);??????????????applyRlimitSecurityPolicy(parsedArgs,?peer);??????????????applyCapabilitiesSecurityPolicy(parsedArgs,?peer);????????????????int[][]?rlimits?=?null;????????????????if?(parsedArgs.rlimits?!=?null)?{??????????????????rlimits?=?parsedArgs.rlimits.toArray(intArray2d);??????????????}????????????????pid?=?Zygote.forkAndSpecialize(parsedArgs.uid,?parsedArgs.gid,??????????????????parsedArgs.gids,?parsedArgs.debugFlags,?rlimits);??????????}?catch?(IllegalArgumentException?ex)?{??????????????......??????????}?catch?(ZygoteSecurityException?ex)?{??????????????......??????????}????????????if?(pid?==?0)?{??????????????????????????handleChildProc(parsedArgs,?descriptors,?newStderr);??????????????????????????return?true;??????????}?else?{?????????????????????????return?handleParentProc(pid,?descriptors,?parsedArgs);??????????}??????}????????......??}?? ?? ? ? ? 真正創(chuàng)建進程的地方就是在這里了:
?
?
[java]?view plaincopy
pid?=?Zygote.forkAndSpecialize(parsedArgs.uid,?parsedArgs.gid,??????parsedArgs.gids,?parsedArgs.debugFlags,?rlimits);?? ?? ? ? ?有Linux開發(fā)經(jīng)驗的讀者很容易看懂這個函數(shù)調(diào)用,這個函數(shù)會創(chuàng)建一個進程,而且有兩個返回值,一個是在當前進程中返回的,一個是在新創(chuàng)建的進程中返回,即在當前進程的子進程中返回,在當前進程中的返回值就是新創(chuàng)建的子進程的pid值,而在子進程中的返回值是0。因為我們只關心創(chuàng)建的新進程的情況,因此,我們沿著子進程的執(zhí)行路徑繼續(xù)看下去:
?
?
[java]?view plaincopy
???if?(pid?==?0)?{??handleChildProc(parsedArgs,?descriptors,?newStderr);??return?true;?????}?else?{?......?????}?? ?? ? ? ?這里就是調(diào)用handleChildProc函數(shù)了。
?
?? ? ? ?Step 7.?ZygoteConnection.handleChildProc
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
?
[java]?view plaincopy
class?ZygoteConnection?{??????......????????private?void?handleChildProc(Arguments?parsedArgs,??????????????FileDescriptor[]?descriptors,?PrintStream?newStderr)??????????????throws?ZygoteInit.MethodAndArgsCaller?{??????????......????????????if?(parsedArgs.runtimeInit)?{??????????????RuntimeInit.zygoteInit(parsedArgs.remainingArgs);??????????}?else?{??????????????......??????????}??????}????????......??}?? ?? ? ? ?由于在前面的Step 3中,指定了"--runtime-init"參數(shù),表示要為新創(chuàng)建的進程初始化運行時庫,因此,這里的parseArgs.runtimeInit值為true,于是就繼續(xù)執(zhí)行RuntimeInit.zygoteInit進一步處理了。
?
?? ? ? ?Step 8.?RuntimeInit.zygoteInit
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
[java]?view plaincopy
public?class?RuntimeInit?{??????......????????public?static?final?void?zygoteInit(String[]?argv)??????????????throws?ZygoteInit.MethodAndArgsCaller?{??????????????????????????????????System.setOut(new?AndroidPrintStream(Log.INFO,?"System.out"));??????????System.setErr(new?AndroidPrintStream(Log.WARN,?"System.err"));????????????commonInit();??????????zygoteInitNative();????????????int?curArg?=?0;??????????for?(?????????????String?arg?=?argv[curArg];????????????????if?(arg.equals("--"))?{??????????????????curArg++;??????????????????break;??????????????}?else?if?(!arg.startsWith("--"))?{??????????????????break;??????????????}?else?if?(arg.startsWith("--nice-name="))?{??????????????????String?niceName?=?arg.substring(arg.indexOf('=')?+?1);??????????????????Process.setArgV0(niceName);??????????????}??????????}????????????if?(curArg?==?argv.length)?{??????????????Slog.e(TAG,?"Missing?classname?argument?to?RuntimeInit!");??????????????????????????return;??????????}??????????????????????String?startClass?=?argv[curArg++];??????????String[]?startArgs?=?new?String[argv.length?-?curArg];????????????System.arraycopy(argv,?curArg,?startArgs,?0,?startArgs.length);??????????invokeStaticMain(startClass,?startArgs);??????}????????......??}?? ?? ? ? ?這里有兩個關鍵的函數(shù)調(diào)用,一個是zygoteInitNative函數(shù)調(diào)用,一個是invokeStaticMain函數(shù)調(diào)用,前者就是執(zhí)行Binder驅(qū)動程序初始化的相關工作了,正是由于執(zhí)行了這個工作,才使得進程中的Binder對象能夠順利地進行Binder進程間通信,而后一個函數(shù)調(diào)用,就是執(zhí)行進程的入口函數(shù),這里就是執(zhí)行startClass類的main函數(shù)了,而這個startClass即是我們在Step 1中傳進來的"android.app.ActivityThread"值,表示要執(zhí)行android.app.ActivityThread類的main函數(shù)。
?
?? ? ? ?我們先來看一下zygoteInitNative函數(shù)的調(diào)用過程,然后再回到RuntimeInit.zygoteInit函數(shù)中來,看看它是如何調(diào)用android.app.ActivityThread類的main函數(shù)的。
?? ? ? ?step 9.?RuntimeInit.zygoteInitNative
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
?
[java]?view plaincopy
public?class?RuntimeInit?{??????......????????public?static?final?native?void?zygoteInitNative();????????......??}?? ?? ? ? ?這里可以看出,函數(shù)zygoteInitNative是一個Native函數(shù),實現(xiàn)在frameworks/base/core/jni/AndroidRuntime.cpp文件中:
?
?
[cpp]?view plaincopy
static?void?com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv*?env,?jobject?clazz)??{??????gCurRuntime->onZygoteInit();??}?? ?
?? ? ? ?這里它調(diào)用了全局變量gCurRuntime的onZygoteInit函數(shù),這個全局變量的定義在frameworks/base/core/jni/AndroidRuntime.cpp文件開頭的地方:
?
[cpp]?view plaincopy
static?AndroidRuntime*?gCurRuntime?=?NULL;?? ?? ? ? ?這里可以看出,它的類型為AndroidRuntime,它是在AndroidRuntime類的構(gòu)造函數(shù)中初始化的,AndroidRuntime類的構(gòu)造函數(shù)也是定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中:
?
?
[cpp]?view plaincopy
AndroidRuntime::AndroidRuntime()??{??????......????????assert(gCurRuntime?==?NULL);????????????gCurRuntime?=?this;??}?? ?? ? ? ?那么這個AndroidRuntime類的構(gòu)造函數(shù)又是什么時候被調(diào)用的呢?AndroidRuntime類的聲明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,如果我們打開這個文件會看到,它是一個虛擬類,也就是我們不能直接創(chuàng)建一個AndroidRuntime對象,只能用一個AndroidRuntime類的指針來指向它的某一個子類,這個子類就是AppRuntime了,它定義在frameworks/base/cmds/app_process/app_main.cpp文件中:
?
?
[cpp]?view plaincopy
int?main(int?argc,?const?char*?const?argv[])??{??????......????????AppRuntime?runtime;????????????......??}?? ?? ? ? ?而AppRuntime類繼續(xù)了AndroidRuntime類,它也是定義在frameworks/base/cmds/app_process/app_main.cpp文件中:
[cpp]?view plaincopy
class?AppRuntime?:?public?AndroidRuntime??{??????......????};?? ?? ? ? ?因此,在前面的com_android_internal_os_RuntimeInit_zygoteInit函數(shù),實際是執(zhí)行了AppRuntime類的onZygoteInit函數(shù)。
?
?? ? ? ?Step 10.?AppRuntime.onZygoteInit
?? ? ? ?這個函數(shù)定義在frameworks/base/cmds/app_process/app_main.cpp文件中:
?
[cpp]?view plaincopy
class?AppRuntime?:?public?AndroidRuntime??{??????......????????virtual?void?onZygoteInit()??????{??????????sp<ProcessState>?proc?=?ProcessState::self();??????????if?(proc->supportsProcesses())?{??????????????LOGV("App?process:?starting?thread?pool.\n");??????????????proc->startThreadPool();??????????}??????}????????......??};?? ?? ? ? ?這里它就是調(diào)用ProcessState::startThreadPool啟動線程池了,這個線程池中的線程就是用來和Binder驅(qū)動程序進行交互的了。
?? ? ? ?Step 11.?ProcessState.startThreadPool
?? ? ? ?這個函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
?
?
[cpp]?view plaincopy
void?ProcessState::startThreadPool()??{??????AutoMutex?_l(mLock);??????if?(!mThreadPoolStarted)?{??????????mThreadPoolStarted?=?true;??????????spawnPooledThread(true);??????}??}?? ?? ? ? ?ProcessState類是Binder進程間通信機制的一個基礎組件,它的作用可以參考淺談Android系統(tǒng)進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路、Android系統(tǒng)進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析和Android系統(tǒng)進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析這三篇文章。這里它調(diào)用spawnPooledThread函數(shù)進一步處理。
?
?? ? ? ?Step 12.?ProcessState.spawnPooledThread
?? ? ? ?這個函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
?
[cpp]?view plaincopy
void?ProcessState::spawnPooledThread(bool?isMain)??{??????if?(mThreadPoolStarted)?{??????????int32_t?s?=?android_atomic_add(1,?&mThreadPoolSeq);??????????char?buf[32];??????????sprintf(buf,?"Binder?Thread?#%d",?s);??????????LOGV("Spawning?new?pooled?thread,?name=%s\n",?buf);??????????sp<Thread>?t?=?new?PoolThread(isMain);??????????t->run(buf);??????}??}?? ?? ? ? ?這里它會創(chuàng)建一個PoolThread線程類,然后執(zhí)行它的run函數(shù),最終就會執(zhí)行PoolThread類的threadLoop函數(shù)了。
?
?? ? ? ?Step 13.?PoolThread.threadLoop
?? ? ? ?這個函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
?
[cpp]?view plaincopy
class?PoolThread?:?public?Thread??{??public:??????PoolThread(bool?isMain)??????????:?mIsMain(isMain)??????{??????}????protected:??????virtual?bool?threadLoop()??????{??????????IPCThreadState::self()->joinThreadPool(mIsMain);??????????return?false;??????}????????const?bool?mIsMain;??};?? ?? ? ? ?這里它執(zhí)行了IPCThreadState::joinThreadPool函數(shù)進一步處理。IPCThreadState也是Binder進程間通信機制的一個基礎組件,它的作用可以參考淺談Android系統(tǒng)進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路、Android系統(tǒng)進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析和Android系統(tǒng)進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析這三篇文章。
?
?? ? ? ?Step 14.?IPCThreadState.joinThreadPool
?? ? ? ?這個函數(shù)定義在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
?
[cpp]?view plaincopy
void?IPCThreadState::joinThreadPool(bool?isMain)??{??????......????????mOut.writeInt32(isMain???BC_ENTER_LOOPER?:?BC_REGISTER_LOOPER);????????......????????status_t?result;??????do?{??????????int32_t?cmd;????????????......????????????????????result?=?talkWithDriver();??????????if?(result?>=?NO_ERROR)?{??????????????size_t?IN?=?mIn.dataAvail();??????????????if?(IN?<?sizeof(int32_t))?continue;??????????????cmd?=?mIn.readInt32();??????????????......????????????????result?=?executeCommand(cmd);??????????}????????????......??????}?while?(result?!=?-ECONNREFUSED?&&?result?!=?-EBADF);????????......????????????mOut.writeInt32(BC_EXIT_LOOPER);??????talkWithDriver(false);??}?? ?? ? ? ?這個函數(shù)首先告訴Binder驅(qū)動程序,這條線程要進入循環(huán)了:
?
?
[cpp]?view plaincopy
mOut.writeInt32(isMain???BC_ENTER_LOOPER?:?BC_REGISTER_LOOPER);?? ?? ? ? ?然后在中間的while循環(huán)中通過talkWithDriver不斷與Binder驅(qū)動程序進行交互,以便獲得Client端的進程間調(diào)用:
?
?
[cpp]?view plaincopy
result?=?talkWithDriver();?? ?? ? ? ?獲得了Client端的進程間調(diào)用后,就調(diào)用excuteCommand函數(shù)來處理這個請求:
?
?
[cpp]?view plaincopy
result?=?executeCommand(cmd);?? ?? ? ? ?最后,線程退出時,也會告訴Binder驅(qū)動程序,它退出了,這樣Binder驅(qū)動程序就不會再在Client端的進程間調(diào)用分發(fā)給它了:
?
?
[cpp]?view plaincopy
mOut.writeInt32(BC_EXIT_LOOPER);??talkWithDriver(false);?? ?? ? ? ?我們再來看看talkWithDriver函數(shù)的實現(xiàn)。
?
?? ? ? ?Step 15. talkWithDriver
?? ? ? ?這個函數(shù)定義在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
?
[cpp]?view plaincopy
status_t?IPCThreadState::talkWithDriver(bool?doReceive)??{??????......????????binder_write_read?bwr;????????????const?bool?needRead?=?mIn.dataPosition()?>=?mIn.dataSize();????????????????????const?size_t?outAvail?=?(!doReceive?||?needRead)???mOut.dataSize()?:?0;????????bwr.write_size?=?outAvail;??????bwr.write_buffer?=?(long?unsigned?int)mOut.data();????????????if?(doReceive?&&?needRead)?{??????????bwr.read_size?=?mIn.dataCapacity();??????????bwr.read_buffer?=?(long?unsigned?int)mIn.data();??????}?else?{??????????bwr.read_size?=?0;??????}????????......????????????if?((bwr.write_size?==?0)?&&?(bwr.read_size?==?0))?return?NO_ERROR;????????bwr.write_consumed?=?0;??????bwr.read_consumed?=?0;??????status_t?err;??????do?{??????????......??#if?defined(HAVE_ANDROID_OS)??????????if?(ioctl(mProcess->mDriverFD,?BINDER_WRITE_READ,?&bwr)?>=?0)??????????????err?=?NO_ERROR;??????????else??????????????err?=?-errno;??#else??????????err?=?INVALID_OPERATION;??#endif??????????......??????????}??????}?while?(err?==?-EINTR);????????....????????if?(err?>=?NO_ERROR)?{??????????if?(bwr..write_consumed?>?0)?{??????????????if?(bwr.write_consumed?<?(ssize_t)mOut.dataSize())??????????????????mOut.remove(0,?bwr.write_consumed);??????????????else??????????????????mOut.setDataSize(0);??????????}??????????if?(bwr.read_consumed?>?0)?{??????????????mIn.setDataSize(bwr.read_consumed);??????????????mIn.setDataPosition(0);??????????}??????????......??????????return?NO_ERROR;??????}????????return?err;??}?? ?? ? ? ?這個函數(shù)的具體作用可以參考Android系統(tǒng)進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析一文,它只要就是通過ioctl文件操作函數(shù)來和Binder驅(qū)動程序交互的了:
?
?
[cpp]?view plaincopy
ioctl(mProcess->mDriverFD,?BINDER_WRITE_READ,?&bwr)?? ?? ? ? ?有了這個線程池之后,我們在開發(fā)Android應用程序的時候,當我們要和其它進程中進行通信時,只要定義自己的Binder對象,然后把這個Binder對象的遠程接口通過其它途徑傳給其它進程后,其它進程就可以通過這個Binder對象的遠程接口來調(diào)用我們的應用程序進程的函數(shù)了,它不像我們在C++層實現(xiàn)Binder進程間通信機制的Server時,必須要手動調(diào)用IPCThreadState.joinThreadPool函數(shù)來進入一個無限循環(huán)中與Binder驅(qū)動程序交互以便獲得Client端的請求,這樣就實現(xiàn)了我們在文章開頭處說的Android應用程序進程天然地支持Binder進程間通信機制。
?
?? ? ? ?細心的讀者可能會發(fā)現(xiàn),從Step 1到Step 9,都是在Android應用程序框架層運行的,而從Step 10到Step 15,都是在Android系統(tǒng)運行時庫層運行的,這兩個層次中的Binder進程間通信機制的接口一個是用Java來實現(xiàn)的,而別一個是用C++來實現(xiàn)的,這兩者是如何協(xié)作的呢?這就是通過JNI層來實現(xiàn)的了,具體可以參考Android系統(tǒng)進程間通信Binder機制在應用程序框架層的Java接口源代碼分析一文。
?? ? ? ?回到Step 8中的RuntimeInit.zygoteInit函數(shù)中,在初始化完成Binder進程間通信機制的基礎設施后,它接著就要進入進程的入口函數(shù)了。
?? ? ? ?Step 16.?RuntimeInit.invokeStaticMain
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
?
[java]?view plaincopy
public?class?ZygoteInit?{??????......????????static?void?invokeStaticMain(ClassLoader?loader,??????????????String?className,?String[]?argv)??????????????throws?ZygoteInit.MethodAndArgsCaller?{??????????Class<?>?cl;????????????try?{??????????????cl?=?loader.loadClass(className);??????????}?catch?(ClassNotFoundException?ex)?{??????????????......??????????}????????????Method?m;??????????try?{??????????????m?=?cl.getMethod("main",?new?Class[]?{?String[].class?});??????????}?catch?(NoSuchMethodException?ex)?{??????????????......??????????}?catch?(SecurityException?ex)?{??????????????......??????????}????????????int?modifiers?=?m.getModifiers();??????????......????????????????????throw?new?ZygoteInit.MethodAndArgsCaller(m,?argv);??????}????????......??}?? ?? ? ? ?前面我們說過,這里傳進來的參數(shù)className字符串值為"android.app.ActivityThread",這里就通ClassLoader.loadClass函數(shù)將它加載到進程中:
?
?
[java]?view plaincopy
cl?=?loader.loadClass(className);?? ?? ? ? ?然后獲得它的靜態(tài)成員函數(shù)main:
?
?
[java]?view plaincopy
m?=?cl.getMethod("main",?new?Class[]?{?String[].class?});?? ?? ? ? ?函數(shù)最后并沒有直接調(diào)用這個靜態(tài)成員函數(shù)main,而是通過拋出一個異常ZygoteInit.MethodAndArgsCaller,然后讓ZygoteInit.main函數(shù)在捕獲這個異常的時候再調(diào)用android.app.ActivityThread類的main函數(shù)。為什么要這樣做呢?注釋里面已經(jīng)講得很清楚了,它是為了清理堆棧的,這樣就會讓android.app.ActivityThread類的main函數(shù)覺得自己是進程的入口函數(shù),而事實上,在執(zhí)行android.app.ActivityThread類的main函數(shù)之前,已經(jīng)做了大量的工作了。
?
?? ? ? ?我們看看ZygoteInit.main函數(shù)在捕獲到這個異常的時候做了什么事:
?
[java]?view plaincopy
public?class?ZygoteInit?{??????......????????public?static?void?main(String?argv[])?{??????????try?{??????????????......??????????}?catch?(MethodAndArgsCaller?caller)?{??????????????caller.run();??????????}?catch?(RuntimeException?ex)?{??????????????......??????????}??????}????????......??}?? ?? ? ? ?它執(zhí)行MethodAndArgsCaller的run函數(shù):
?
?
[java]?view plaincopy
public?class?ZygoteInit?{??????......????????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?{??????????????????mMethod.invoke(null,?new?Object[]?{?mArgs?});??????????????}?catch?(IllegalAccessException?ex)?{??????????????????......??????????????}?catch?(InvocationTargetException?ex)?{??????????????????......??????????????}??????????}??????}????????......??}?? ?? ? ? ?這里的成員變量mMethod和mArgs都是在前面構(gòu)造異常對象時傳進來的,這里的mMethod就對應android.app.ActivityThread類的main函數(shù)了,于是最后就通過下面語句執(zhí)行這個函數(shù):
?
?
[java]?view plaincopy
mMethod.invoke(null,?new?Object[]?{?mArgs?});?? ?? ? ? ?這樣,android.app.ActivityThread類的main函數(shù)就被執(zhí)行了。
?
?? ? ? ?Step 17.?ActivityThread.main
?? ? ? ?這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
?
[java]?view plaincopy
public?final?class?ActivityThread?{??????......????????public?static?final?void?main(String[]?args)?{??????????SamplingProfilerIntegration.start();????????????Process.setArgV0("<pre-initialized>");????????????Looper.prepareMainLooper();??????????if?(sMainThreadHandler?==?null)?{??????????????sMainThreadHandler?=?new?Handler();??????????}????????????ActivityThread?thread?=?new?ActivityThread();??????????thread.attach(false);????????????if?(false)?{??????????????Looper.myLooper().setMessageLogging(new??????????????????LogPrinter(Log.DEBUG,?"ActivityThread"));??????????}??????????Looper.loop();????????????if?(Process.supportsProcesses())?{??????????????throw?new?RuntimeException("Main?thread?loop?unexpectedly?exited");??????????}????????????thread.detach();??????????String?name?=?(thread.mInitialApplication?!=?null)????????????????thread.mInitialApplication.getPackageName()??????????????:?"<unknown>";??????????Slog.i(TAG,?"Main?thread?of?"?+?name?+?"?is?now?exiting");??????}????????......??}?? ?? ? ? ?從這里我們可以看出,這個函數(shù)首先會在進程中創(chuàng)建一個ActivityThread對象:
?
?
[java]?view plaincopy
ActivityThread?thread?=?new?ActivityThread();?? ?? ? ? ?然后進入消息循環(huán)中:
?
?
[java]?view plaincopy
Looper.loop();?? ?? ? ? ?這樣,我們以后就可以在這個進程中啟動Activity或者Service了。
?
?? ? ? ?至此,Android應用程序進程啟動過程的源代碼就分析完成了,它除了指定新的進程的入口函數(shù)是ActivityThread的main函數(shù)之外,還為進程內(nèi)的Binder對象提供了Binder進程間通信機制的基礎設施,由此可見,Binder進程間通信機制在Android系統(tǒng)中是何等的重要,而且是無處不在,想進一步學習Android系統(tǒng)的Binder進程間通信機制,請參考Android進程間通信(IPC)機制Binder簡要介紹和學習計劃一文。
轉(zhuǎn)載于:https://www.cnblogs.com/kevincode/p/3940822.html
總結(jié)
以上是生活随笔為你收集整理的Android系统进程Zygote启动过程的源代码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。