原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696java
Android應用程序框架層建立的應用程序進程具備兩個特色,一是進程的入口函數是ActivityThread.main,二是進程自然支持Binder進程間通訊機制;這兩個特色都是在進程的初始化過程當中實現的,本文將詳細分析Android應用程序進程建立過程當中是如何實現這兩個特色的。android
Android應用程序框架層建立的應用程序進程的入口函數是ActivityThread.main比較好理解,即進程建立完成以後,Android應用程序框架層就會在這個進程中將ActivityThread類加載進來,而後執行它的main函數,這個main函數就是進程執行消息循環的地方了。Android應用程序框架層建立的應用程序進程自然支持Binder進程間通訊機制這個特色應該怎麼樣理解呢?前面咱們在學習Android系統的Binder進程間通訊機制時說到,它具備四個組件,分別是驅動程序、守護進程、Client以及Server,其中Server組件在初始化時必須進入一個循環中不斷地與Binder驅動程序進行到交互,以便得到Client組件發送的請求,具體可參考Android系統進程間通訊(IPC)機制Binder中的Server啓動過程源代碼分析一文,可是,當咱們在Android應用程序中實現Server組件的時候,咱們並無讓進程進入一個循環中去等待Client組件的請求,然而,當Client組件獲得這個Server組件的遠程接口時,卻能夠順利地和Server組件進行進程間通訊,這就是由於Android應用程序進程在建立的時候就已經啓動了一個線程池來支持Server組件和Binder驅動程序之間的交互了,這樣,極大地方便了在Android應用程序中建立Server組件。app
在Android應用程序框架層中,是由ActivityManagerService組件負責爲Android應用程序建立新的進程的,它原本也是運行在一個獨立的進程之中,不過這個進程是在系統啓動的過程當中建立的。ActivityManagerService組件通常會在什麼狀況下會爲應用程序建立一個新的進程呢?當系統決定要在一個新的進程中啓動一個Activity或者Service時,它就會建立一個新的進程了,而後在這個新的進程中啓動這個Activity或者Service,具體能夠參考Android系統在新進程中啓動自定義服務過程(startService)的原理分析、Android應用程序啓動過程源代碼分析和Android應用程序在新的進程中啓動新的Activity的方法和過程分析這三篇文章。框架
ActivityManagerService啓動新的進程是從其成員函數startProcessLocked開始的,在深刻分析這個過程以前,咱們先來看一下進程建立過程的序列圖,而後再詳細分析每個步驟。socket
![](http://static.javashuo.com/static/loading.gif)
點擊查看大圖ide
Step 1. ActivityManagerService.startProcessLocked函數
這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:oop
- 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) {
-
- ......
-
- }
- }
-
- ......
-
- }
它調用了Process.start函數開始爲應用程序建立新的進程,注意,它傳入一個第一個參數爲"android.app.ActivityThread",這就是進程初始化時要加載的Java類了,把這個類加載到進程以後,就會把它裏面的靜態成員函數main做爲進程的入口點,後面咱們會看到。學習
Step 2. Process.start ui
這個函數定義在frameworks/base/core/java/android/os/Process.java文件中:
- 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函數返回值爲true,它是一個Native函數,實如今frameworks/base/core/jni/android_util_Process.cpp文件中:
- jboolean android_os_Process_supportsProcesses(JNIEnv* env, jobject clazz)
- {
- return ProcessState::self()->supportsProcesses();
- }
ProcessState::supportsProcesses函數定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
- bool ProcessState::supportsProcesses() const
- {
- return mDriverFD >= 0;
- }
這裏的mDriverFD是設備文件/dev/binder的打開描述符,若是成功打開了這個設備文件,那麼它的值就會大於等於0,所以,它的返回值爲true。
回到Process.start函數中,它調用startViaZygote函數進一步操做。
Step 3. Process.startViaZygote
這個函數定義在frameworks/base/core/java/android/os/Process.java文件中:
- 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);
- }
- }
-
- ......
- }
這個函數將建立進程的參數放到argsForZygote列表中去,如參數"--runtime-init"表示要爲新建立的進程初始化運行時庫,而後調用zygoteSendAndGetPid函數進一步操做。
Step 4. Process.zygoteSendAndGetPid
這個函數定義在frameworks/base/core/java/android/os/Process.java文件中:
- 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函數打開的:
- 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函數偵聽的。
Step 5. ZygoteInit.runSelectLoopMode
這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- 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將數據經過Socket接口發送出去後,就會下面這個語句:
- done = peers.get(index).runOnce();
這裏從peers.get(index)獲得的是一個ZygoteConnection對象,表示一個Socket鏈接,所以,接下來就是調用ZygoteConnection.runOnce函數進一步處理了。
Step 6. ZygoteConnection.runOnce
這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
- 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);
- }
- }
-
- ......
- }
真正建立進程的地方就是在這裏了:
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
有Linux開發經驗的讀者很容易看懂這個函數調用,這個函數會建立一個進程,並且有兩個返回值,一個是在當前進程中返回的,一個是在新建立的進程中返回,即在當前進程的子進程中返回,在當前進程中的返回值就是新建立的子進程的pid值,而在子進程中的返回值是0。由於咱們只關心建立的新進程的狀況,所以,咱們沿着子進程的執行路徑繼續看下去:
- if (pid == 0) {
- handleChildProc(parsedArgs, descriptors, newStderr);
- return true;
- } else {
- ......
- }
這裏就是調用handleChildProc函數了。
Step 7. ZygoteConnection.handleChildProc
這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
- 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"參數,表示要爲新建立的進程初始化運行時庫,所以,這裏的parseArgs.runtimeInit值爲true,因而就繼續執行RuntimeInit.zygoteInit進一步處理了。
Step 8. RuntimeInit.zygoteInit
這個函數定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- 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);
- }
-
- ......
- }
這裏有兩個關鍵的函數調用,一個是zygoteInitNative函數調用,一個是invokeStaticMain函數調用,前者就是執行Binder驅動程序初始化的相關工做了,正是因爲執行了這個工做,才使得進程中的Binder對象可以順利地進行Binder進程間通訊,然後一個函數調用,就是執行進程的入口函數,這裏就是執行startClass類的main函數了,而這個startClass便是咱們在Step 1中傳進來的"android.app.ActivityThread"值,表示要執行android.app.ActivityThread類的main函數。
咱們先來看一下zygoteInitNative函數的調用過程,而後再回到RuntimeInit.zygoteInit函數中來,看看它是如何調用android.app.ActivityThread類的main函數的。
step 9. RuntimeInit.zygoteInitNative
這個函數定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- public class RuntimeInit {
- ......
-
- public static final native void zygoteInitNative();
-
- ......
- }
這裏能夠看出,函數zygoteInitNative是一個Native函數,實如今frameworks/base/core/jni/AndroidRuntime.cpp文件中:
- static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
- {
- gCurRuntime->onZygoteInit();
- }
這裏它調用了全局變量gCurRuntime的onZygoteInit函數,這個全局變量的定義在frameworks/base/core/jni/AndroidRuntime.cpp文件開頭的地方:
- static AndroidRuntime* gCurRuntime = NULL;
這裏能夠看出,它的類型爲AndroidRuntime,它是在AndroidRuntime類的構造函數中初始化的,AndroidRuntime類的構造函數也是定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中:
- AndroidRuntime::AndroidRuntime()
- {
- ......
-
- assert(gCurRuntime == NULL);
- gCurRuntime = this;
- }
那麼這個AndroidRuntime類的構造函數又是何時被調用的呢?AndroidRuntime類的聲明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,若是咱們打開這個文件會看到,它是一個虛擬類,也就是咱們不能直接建立一個AndroidRuntime對象,只能用一個AndroidRuntime類的指針來指向它的某一個子類,這個子類就是AppRuntime了,它定義在frameworks/base/cmds/app_process/app_main.cpp文件中:
- int main(int argc, const char* const argv[])
- {
- ......
-
- AppRuntime runtime;
-
- ......
- }
而AppRuntime類繼續了AndroidRuntime類,它也是定義在frameworks/base/cmds/app_process/app_main.cpp文件中:
- class AppRuntime : public AndroidRuntime
- {
- ......
-
- };
所以,在前面的com_android_internal_os_RuntimeInit_zygoteInit函數,實際是執行了AppRuntime類的onZygoteInit函數。
Step 10. AppRuntime.onZygoteInit
這個函數定義在frameworks/base/cmds/app_process/app_main.cpp文件中:
- class AppRuntime : public AndroidRuntime
- {
- ......
-
- virtual void onZygoteInit()
- {
- sp<ProcessState> proc = ProcessState::self();
- if (proc->supportsProcesses()) {
- LOGV("App process: starting thread pool.\n");
- proc->startThreadPool();
- }
- }
-
- ......
- };
這裏它就是調用ProcessState::startThreadPool啓動線程池了,這個線程池中的線程就是用來和Binder驅動程序進行交互的了。
Step 11. ProcessState.startThreadPool
這個函數定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
- void ProcessState::startThreadPool()
- {
- AutoMutex _l(mLock);
- if (!mThreadPoolStarted) {
- mThreadPoolStarted = true;
- spawnPooledThread(true);
- }
- }
ProcessState類是Binder進程間通訊機制的一個基礎組件,它的做用能夠參考淺談Android系統進程間通訊(IPC)機制Binder中的Server和Client得到Service Manager接口之路、Android系統進程間通訊(IPC)機制Binder中的Server啓動過程源代碼分析和Android系統進程間通訊(IPC)機制Binder中的Client得到Server遠程接口過程源代碼分析這三篇文章。這裏它調用spawnPooledThread函數進一步處理。
Step 12. ProcessState.spawnPooledThread
這個函數定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
- 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);
- }
- }
這裏它會建立一個PoolThread線程類,而後執行它的run函數,最終就會執行PoolThread類的threadLoop函數了。
Step 13. PoolThread.threadLoop
這個函數定義在frameworks/base/libs/binder/ProcessState.cpp文件中:
- class PoolThread : public Thread
- {
- public:
- PoolThread(bool isMain)
- : mIsMain(isMain)
- {
- }
-
- protected:
- virtual bool threadLoop()
- {
- IPCThreadState::self()->joinThreadPool(mIsMain);
- return false;
- }
-
- const bool mIsMain;
- };
這裏它執行了IPCThreadState::joinThreadPool函數進一步處理。IPCThreadState也是Binder進程間通訊機制的一個基礎組件,它的做用能夠參考淺談Android系統進程間通訊(IPC)機制Binder中的Server和Client得到Service Manager接口之路、Android系統進程間通訊(IPC)機制Binder中的Server啓動過程源代碼分析和Android系統進程間通訊(IPC)機制Binder中的Client得到Server遠程接口過程源代碼分析這三篇文章。
Step 14. IPCThreadState.joinThreadPool
這個函數定義在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
- 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);
- }
這個函數首先告訴Binder驅動程序,這條線程要進入循環了:
- mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
而後在中間的while循環中經過talkWithDriver不斷與Binder驅動程序進行交互,以便得到Client端的進程間調用:
- result = talkWithDriver();
得到了Client端的進程間調用後,就調用excuteCommand函數來處理這個請求:
- result = executeCommand(cmd);
最後,線程退出時,也會告訴Binder驅動程序,它退出了,這樣Binder驅動程序就不會再在Client端的進程間調用分發給它了:
- mOut.writeInt32(BC_EXIT_LOOPER);
- talkWithDriver(false);
咱們再來看看talkWithDriver函數的實現。
Step 15. talkWithDriver
這個函數定義在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
- 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;
- }
這個函數的具體做用能夠參考Android系統進程間通訊(IPC)機制Binder中的Server啓動過程源代碼分析一文,它只要就是經過ioctl文件操做函數來和Binder驅動程序交互的了:
- ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)
有了這個線程池以後,咱們在開發Android應用程序的時候,當咱們要和其它進程中進行通訊時,只要定義本身的Binder對象,而後把這個Binder對象的遠程接口經過其它途徑傳給其它進程後,其它進程就能夠經過這個Binder對象的遠程接口來調用咱們的應用程序進程的函數了,它不像咱們在C++層實現Binder進程間通訊機制的Server時,必需要手動調用IPCThreadState.joinThreadPool函數來進入一個無限循環中與Binder驅動程序交互以便得到Client端的請求,這樣就實現了咱們在文章開頭處說的Android應用程序進程自然地支持Binder進程間通訊機制。
細心的讀者可能會發現,從Step 1到Step 9,都是在Android應用程序框架層運行的,而從Step 10到Step 15,都是在Android系統運行時庫層運行的,這兩個層次中的Binder進程間通訊機制的接口一個是用Java來實現的,而別一個是用C++來實現的,這二者是如何協做的呢?這就是經過JNI層來實現的了,具體能夠參考Android系統進程間通訊Binder機制在應用程序框架層的Java接口源代碼分析一文。
回到Step 8中的RuntimeInit.zygoteInit函數中,在初始化完成Binder進程間通訊機制的基礎設施後,它接着就要進入進程的入口函數了。
Step 16. RuntimeInit.invokeStaticMain
這個函數定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- 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);
- }
-
- ......
- }
前面咱們說過,這裏傳進來的參數className字符串值爲"android.app.ActivityThread",這裏就通ClassLoader.loadClass函數將它加載到進程中:
- cl = loader.loadClass(className);
而後得到它的靜態成員函數main:
- m = cl.getMethod("main", new Class[] { String[].class });
函數最後並無直接調用這個靜態成員函數main,而是經過拋出一個異常ZygoteInit.MethodAndArgsCaller,而後讓ZygoteInit.main函數在捕獲這個異常的時候再調用android.app.ActivityThread類的main函數。爲何要這樣作呢?註釋裏面已經講得很清楚了,它是爲了清理堆棧的,這樣就會讓android.app.ActivityThread類的main函數以爲本身是進程的入口函數,而事實上,在執行android.app.ActivityThread類的main函數以前,已經作了大量的工做了。
咱們看看ZygoteInit.main函數在捕獲到這個異常的時候作了什麼事:
- public class ZygoteInit {
- ......
-
- public static void main(String argv[]) {
- try {
- ......
- } catch (MethodAndArgsCaller caller) {
- caller.run();
- } catch (RuntimeException ex) {
- ......
- }
- }
-
- ......
- }
它執行MethodAndArgsCaller的run函數:
- 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都是在前面構造異常對象時傳進來的,這裏的mMethod就對應android.app.ActivityThread類的main函數了,因而最後就經過下面語句執行這個函數:
- mMethod.invoke(null, new Object[] { mArgs });
這樣,android.app.ActivityThread類的main函數就被執行了。
Step 17. ActivityThread.main
這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- 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");
- }
-
- ......
- }
從這裏咱們能夠看出,這個函數首先會在進程中建立一個ActivityThread對象:
- ActivityThread thread = new ActivityThread();
而後進入消息循環中:
這樣,咱們之後就能夠在這個進程中啓動Activity或者Service了。
至此,Android應用程序進程啓動過程的源代碼就分析完成了,它除了指定新的進程的入口函數是ActivityThread的main函數以外,還爲進程內的Binder對象提供了Binder進程間通訊機制的基礎設施,因而可知,Binder進程間通訊機制在Android系統中是何等的重要,並且是無處不在,想進一步學習Android系統的Binder進程間通訊機制,請參考Android進程間通訊(IPC)機制Binder簡要介紹和學習計劃一文。