4.4.2 有求必应之响应请求
最后更新于:2022-04-02 05:49:19
前面有一节,题目叫“有求必应之等待请求”,那么这一节“有求必应之响应请求”会回到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命令查看进程和父进程号来确认。
';