原文地址: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

点击查看大图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简要介绍和学习计划一文。