💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
前面有一节,题目叫“有求必应之等待请求”,那么这一节“有求必应之响应请求”会回到ZygoteInit。下面就看看它是如何处理请求的。 **ZygoteInit.java** ~~~ private static void runSelectLoopMode() throwsMethodAndArgsCaller{ ...... try { fdArray = fds.toArray(fdArray); ...... else if (index == 0) { ZygoteConnection newPeer = acceptCommandPeer(); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { boolean done; //调用ZygoteConnection的runOnce done = peers.get(index).runOnce(); } ...... } ~~~ 每当有请求数据发来时,Zygote都会调用ZygoteConnection的runOnce函数。ZygoteConnection代码在ZygoteConnection.java文件中,来看看它的runOnce函数: **ZygoteConnection.java** ~~~ boolean runOnce() throwsZygoteInit.MethodAndArgsCaller { try { args = readArgumentList();//读取SS发送过来的参数 descriptors = mSocket.getAncillaryFileDescriptors(); } ...... int pid; try { parsedArgs = new Arguments(args); applyUidSecurityPolicy(parsedArgs, peer); //根据函数名,可知Zygote又分裂出了一个子进程。 pid =Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,parsedArgs.debugFlags, rlimits); } ...... if(pid == 0) { //子进程处理,这个子进程是不是我们要创建的Activity对应的子进程呢? handleChildProc(parsedArgs, descriptors, newStderr); return true; }else { //zygote进程 return handleParentProc(pid, descriptors, parsedArgs); } } ~~~ 接下来,看看新创建的子进程在handleChildProc中做了些什么。 **ZygoteConnection.java** ~~~ private void handleChildProc(ArgumentsparsedArgs,FileDescriptor[] descriptors, PrintStream newStderr) throwsZygoteInit.MethodAndArgsCaller { ......//根据传入的参数设置新进程的一些属性 //SS发来的参数中有“--runtime-init“,所以parsedArgs.runtimeInit为true。 if(parsedArgs.runtimeInit) { RuntimeInit.zygoteInit(parsedArgs.remainingArgs); }else { ...... } } ~~~ **RuntimeInit.java** ~~~ 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(); //下面这个函数为native函数,最终会调用AppRuntime的onZygoteInit,在那个函数中 //建立了和Binder的关系 zygoteInitNative(); int curArg = 0; ...... String startClass = argv[curArg++]; String[] startArgs = new String[argv.length - curArg]; System.arraycopy(argv, curArg, startArgs, 0, startArgs.length); //最终还是调用invokeStaticMain函数,这个函数我们已经见识过了。 invokeStaticMain(startClass, startArgs); } ~~~ Zygote分裂子进程后,自己将在handleParentProc中做一些扫尾工作,然后继续等待请求进行下一次分裂。 >[info]**提示**:这个android.app.ActivityThread类,实际上是Android中apk程序所对应的进程,它的main函数就是apk程序的main函数。从这个类的命名(android.app)中也可以看出些端倪。 通过这一节的分析,读者可以想到,Android系统运行的那些apk程序,其父都是zygote。这一点,可以通过adb shell登录后,用ps命令查看进程和父进程号来确认。