其中:
- openZygoteSocketIfNeeded打开本地socket
- zygoteSendArgsAndGetResult发送请求参数,其中带上了ActivityThread类名
- return返回的数据结构ProcessStartResult中会有pid字段

文章插图
注意:Zygote进程启动时已经创建好了虚拟机实例,所以由他fork出的应用进程可以直接继承过来用而无需创建 。
下面来看Zygote是如何处理socket请求的 。
Zygote处理socket请求从 图解Android系统的启动 一文可知,在ZygoteInit的main函数中,会创建服务端socket 。
//ZygoteInit.javapublic static void main(String argv[]) {//Server类,封装了socketZygoteServer zygoteServer = new ZygoteServer();//创建服务端socket,名字为socketName即zygotezygoteServer.registerServerSocket(socketName);//进入死循环,等待AMS发请求过来zygoteServer.runSelectLoop(abiList);} 【搞懂Android应用启动过程,再也不怕面试官了】看到ZygoteServer 。//ZygoteServer.javavoid registerServerSocket(String socketName) {int fileDesc;//socket真正的名字被加了个前缀,即 "ANDROID_SOCKET_" + "zygote"final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;String env = System.getenv(fullSocketName);fileDesc = Integer.parseInt(env);//创建文件描述符fdFileDescriptor fd = new FileDescriptor();fd.setInt$(fileDesc);//创建LocalServerSocket对象mServerSocket = new LocalServerSocket(fd);}void runSelectLoop(String abiList){//进入死循环while (true) {for (int i = pollFds.length - 1; i >= 0; --i) {if (i == 0) {//...} else {//得到一个连接对象ZygoteConnection,调用他的runOnceboolean done = peers.get(i).runOnce(this);}}}} 来到ZygoteConnection的runOnce 。boolean runOnce(ZygoteServer zygoteServer){//读取socket请求的参数列表String args[] = readArgumentList();//创建应用进程int pid = Zygote.forkAndSpecialize(...);if (pid == 0) {//如果是应用进程(Zygote fork出来的子进程),处理请求参数handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);return true;} else {return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);}} handleChildProc方法调用了ZygoteInit的zygoteInit方法,里边主要做了3件事:- 启动binder线程池(后面分析)
- 读取请求参数拿到ActivityThread类并执行他的main函数,执行thread.attach告知AMS并回传自己的binder句柄
- 执行Looper.loop()启动消息循环(代码前面有)

文章插图
下面看下binder线程池是怎么启动的 。
启动binder线程池Zygote的跨进程通信没有使用binder,而是socket,所以应用进程的binder机制不是继承而来,而是进程创建后自己启动的 。
前边可知,Zygote收到socket请求后会得到一个ZygoteConnection,他的runOnce会调用handleChildProc 。
//ZygoteConnection.javaprivate void handleChildProc(...){ZygoteInit.zygoteInit(...);}//ZygoteInit.javapublic static final void zygoteInit(...){RuntimeInit.commonInit();//进入native层ZygoteInit.nativeZygoteInit();RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);} 来到AndroidRuntime.cpp://AndroidRuntime.cppstatic void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz){gCurRuntime->onZygoteInit();} 来到app_main.cpp://app_main.cppvirtual void onZygoteInit() {//获取单例sp<ProcessState> proc = ProcessState::self();//在这里启动了binder线程池proc->startThreadPool();} 看下ProcessState.cpp://ProcessState.cppsp<ProcessState> ProcessState::self(){//单例模式,返回ProcessState对象if (gProcess != NULL) {return gProcess;}gProcess = new ProcessState("/dev/binder");return gProcess;}//ProcessState构造函数ProcessState::ProcessState(const char *driver): mDriverName(String8(driver)), mDriverFD(open_driver(driver)) //打开binder驱动,//...{if (mDriverFD >= 0) {//mmap是一种内存映射文件的方法,把mDriverFD映射到当前的内存空间mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);}}//启动了binder线程池void ProcessState::startThreadPool(){if (!mThreadPoolStarted) {mThreadPoolStarted = true;spawnPooledThread(true);}}void ProcessState::spawnPooledThread(bool isMain){if (mThreadPoolStarted) {//创建线程名字"Binder:${pid}_${自增数字}"String8 name = makeBinderThreadName();sp<Thread> t = new PoolThread(isMain);//运行binder线程t->run(name.string());}} ProcessState有两个宏定义值得注意一下:
推荐阅读
- 常用iOS应用的小组件推荐!超实用
- 6张图让你搞懂浏览器渲染网页过程
- Linux 上部署 Java 应用绕不开的命令,撒花啦
- 应用程序合成生成交换机代码
- 详解 gcc 编译、链接原理—揭开应用程序运行背后的奥秘
- Netflix如何实现Android与 iOS共用一套代码?
- 锌锰干电池原理和应用介绍
- 电池修复仪原理介绍及应用
- 恋爱行为学的实际应用解析
- 全方位理解哈希算法及其应用,不再迷茫
