标签:
上一篇文章我们已经分析到调用com.android.internal.os.ZygoteInit类的main函数。
今天分析一下com.android.internal.os.ZygoteInit类的main函数。
public static void main(String argv[]) { // 注册zygote的socket
registerZygoteSocket(); /** * 处理客户端连接及请求。由zygoteConnection的runOnce函数来处理。
*/ runSelectLoopMode();
}
在main函数我们就主要看registerZygoteSocket()与runSelectLoopMode()。
那么我们就看一下registerZygoteSocket()
private static void registerZygoteSocket() { String env = System.getenv(ANDROID_SOCKET_ENV); fileDesc = Integer.parseInt(env); if (sServerSocket == null) { sServerSocket = new LocalServerSocket( createFileDescriptor(fileDesc)); } }
很简单就是创建一个LocalServerSocket。
建立IPC通信服务器,从环境变量中获取(System.getenv(ANDROID_SOCKET_ENV);)socket的fd,之前用sig的fd来调用handle去创建的zygote。
这里没有提到
PreloadClass读取framework/base/tools/preload/preload_class文件约1268类。
PreloadResources加载framework-res.apk中的资源。
了解一下就好。
我们在来看一下runSelectLoopMode()
private static void runSelectLoopMode() throws MethodAndArgsCaller { … while (true) { int index; fdArray = fds.toArray(fdArray); index = selectReadable(fdArray); if(index == 0) { //连接客户端发送的请求(Command) ZygoteConnection newPeer = acceptCommandPeer(); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { //处理客户端发送的请求(Command) boolean done; done = peers.get(index).runOnce(); } } }
这个函数也很简单等待客户端发来的请求,当接收到请求时就运行run0nce函数去处理请求即可。
客户端可以理解成AMS或SystemServer。
在这里简单说明一下AMS与SystemServer
Zygote的子进程,为JAVA世界做服务。
Java世界系统Service,此进程是framework的核心,此server挂掉了,zygote会自杀。
Zygote.forkSystemServer()而诞生。
ActivityManagerService是由SystemServer创建。
当一个Acitvity开启的时候,是由AMS中开启一个新的Process,而在Process类中最终会创建一个LocalSocket去连接ZYGOTE_SOCKET。
而在AMS中的startProcessLocked()中调用Process.start()函数中会传入一个参数-android.app.ActivityThread。最终会通过socket传入zygote处理。
我们继续看以下done = peers.get(index).runOnce();
boolean runOnce( ) { Arguments parsedArgs = null; FileDescriptor[] descriptors; //Reads command socket. args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); try { parsedArgs = new Arguments(args); ...... pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName); } catch (IOException ex) { ...... } catch (ErrnoException ex) { ...... } catch (IllegalArgumentException ex) { ...... } catch (ZygoteSecurityException ex) { ...... } //新创建的进程 pid == 0
if (pid == 0) { // in child serverPipeFd = null; handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); return true; } else { // in parent,也就是Zygote进程执行过程
childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } }
我们分析一下以下几个函数
首先我们来看一下forkAndSpecialize()
这个函数定义在文件libcore/dalvik/src/main/java/dalvik/system/Zygote.java中。
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName) { preFork(); int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName); postFork(); return pid; }
很简单就是调用native的ForkAndSpecialize函数。
JNI函数nativeForkAndSpecialize的由Dalvik_dalvik_system_Zygote_forkAndSpecialize函数来实现。
那我们就去看一下。
这个函数定义在文件dalvik/vm/native/dalvik_system_Zygote.cpp中。
static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args, JValue* pResult) {
pid_t pid;
//args指向的一块内存中 pid = forkAndSpecializeCommon(args, false); RETURN_INT(pid); }
Dalvik_dalvik_system_Zygote_forkAndSpecialize函数通过调用forkAndSpecializeCommon函数来执行创建进程,
实现如下所示:
这个函数定义在文件dalvik/vm/native/dalvik_system_Zygote.cpp中。
static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer) { pid_t pid; uid_t uid = (uid_t) args[0]; gid_t gid = (gid_t) args[1]; ...... char *seInfo = NULL; char *niceName = NULL; if (isSystemServer) { //参数isSystemServer表示true时创建的是System Server进程。
...... } else { //参数isSystemServer表示true时创建的是应用程序进程。
...... } ...... pid = fork(); //表示当前是新创建的进程 if (pid == 0) { ...... err = setSELinuxContext(uid, isSystemServer, seInfo, niceName); ...... } ...... return pid; }
我们不去看具体代码实现,主要了解一下主要是干什么的就可以了。
我们要知道的是zygote是负责应用程序进程与SystemServer的进程就可以了。
接下来我们回到之前的handleParentProc()
private boolean handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) { if (pid > 0) { setChildPgid(pid); } if (descriptors != null) { for (FileDescriptor fd: descriptors) { IoUtils.closeQuietly(fd); } } boolean usingWrapper = false; if (pipeFd != null && pid > 0) { DataInputStream is = new DataInputStream(new FileInputStream(pipeFd)); int innerPid = -1; try { innerPid = is.readInt(); } catch (IOException ex) { Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex); } finally { try { is.close(); } catch (IOException ex) { } } // Ensure that the pid reported by the wrapped process is either the // child process that we forked, or a descendant of it. if (innerPid > 0) { int parentPid = innerPid; while (parentPid > 0 && parentPid != pid) { parentPid = Process.getParentPid(parentPid); } if (parentPid > 0) { Log.i(TAG, "Wrapped process has pid " + innerPid); pid = innerPid; usingWrapper = true; } else { Log.w(TAG, "Wrapped process reported a pid that is not a child of " + "the process that we forked: childPid=" + pid + " innerPid=" + innerPid); } } } //将创建的应用程序进程ID返回给SystemServer进程的ActivityManagerService服务 try { mSocketOutStream.writeInt(pid); mSocketOutStream.writeBoolean(usingWrapper); } catch (IOException ex) { Log.e(TAG, "Error reading from command socket", ex); return true; } /* * If the peer wants to use the socket to wait on the * newly spawned process, then we‘re all done. */ if (parsedArgs.peerWait) { try { mSocket.close(); } catch (IOException ex) { Log.e(TAG, "Zygote: error closing sockets", ex); } return true; } return false; }
也就是创建失败会进入此函数,也就是处理zygote进程的函数,此函数会原路返回,通过socket的写入返还给systemserver最终到AMS,然后重新进入runSelectLoopMode。继续监听客户端的请求。
如果我们新创建进程成功了,会调用handleChildProc()。
代码如下
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { /* * Close the socket, unless we‘re in "peer wait" mode, in which * case it‘s used to track the liveness of this process. */ if (parsedArgs.peerWait) { try { ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true); sPeerWaitSocket = mSocket; } catch (IOException ex) { Log.e(TAG, "Zygote Child: error setting peer wait " + "socket to be close-on-exec", ex); } } else {//关闭从Zygote进程复制过来的Socket连接 closeSocket(); ZygoteInit.closeServerSocket(); } if (descriptors != null) { try { //为新创建的应用程序进程重新打开标准输入输出控制台 ZygoteInit.reopenStdio(descriptors[0],descriptors[1], descriptors[2]); for (FileDescriptor fd: descriptors) { IoUtils.closeQuietly(fd); } newStderr = System.err; } catch (IOException ex) { Log.e(TAG, "Error reopening stdio", ex); } } //设置新进程名称 if (parsedArgs.niceName != null) { //设置新进程名称niceName是指systemServer
Process.setArgV0(parsedArgs.niceName); } //重新初始化Runtime if (parsedArgs.runtimeInit) { if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, pipeFd, parsedArgs.remainingArgs); } else { //为应用程序进程启动Binder线程池 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs); } } else { String className; try { //读取新进程执行的类名,在Process.start()函数中,传过来的类名为:"android.app.ActivityThread" className = parsedArgs.remainingArgs[0]; } catch (ArrayIndexOutOfBoundsException ex) { logAndPrintError(newStderr,"Missing required class name argument", null); return; } String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1]; System.arraycopy(parsedArgs.remainingArgs, 1,mainArgs, 0, mainArgs.length); if (parsedArgs.invokeWith != null) { WrapperInit.execStandalone(parsedArgs.invokeWith,parsedArgs.classpath, className, mainArgs); } else { //获取类加载器 ClassLoader cloader; if (parsedArgs.classpath != null) { cloader = new PathClassLoader(parsedArgs.classpath,ClassLoader.getSystemClassLoader()); } else { cloader = ClassLoader.getSystemClassLoader(); } //加载并执行"android.app.ActivityThread"类 try { ZygoteInit.invokeStaticMain(cloader, className, mainArgs); } catch (RuntimeException ex) { logAndPrintError(newStderr, "Error starting.", ex); } } } }
由于应用程序启动参数中已经设置了"--runtime-init"标志位,因此新创建的应用程序进程将调用RuntimeInit.zygoteInit()函数来初始化运行时库,为应用程序启动Binder线程池,完成这些准备工作后,调用应用程序进程的入口函数ActivityThread.main()为应用程序进程创建消息循环。
接下来我们就看一下RuntimeInit.zygoteInit()
此函数在/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java中
public static final void zygoteInit(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller { if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); //重定向Log输出流 redirectLogStreams(); //初始化运行环境 commonInit(); //启动Binder线程池 nativeZygoteInit(); //调用程序入口函数 applicationInit(targetSdkVersion, argv); }
接下来我们看一下applicationInit()
private static void applicationInit(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller { // If the application calls System.exit(), terminate the process // immediately without running any shutdown hooks. It is not possible to // shutdown an Android application gracefully. Among other things, the // Android runtime shutdown hooks close the Binder driver, which can cause // leftover running threads to crash before the process actually exits. nativeSetExitWithoutCleanup(true); // We want to be fairly aggressive about heap utilization, to avoid // holding on to a lot of memory that isn‘t needed. VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args; try { args = new Arguments(argv); } catch (IllegalArgumentException ex) { Slog.e(TAG, ex.getMessage()); // let the process exit return; } // Remaining arguments are passed to the start class‘s static main invokeStaticMain(args.startClass, args.startArgs); }
在这里我们重点要看一下invokeStaticMain()
通过调用invokeStaticMain来调用args.startClass这个类的main()方法。
说明开启又一个新世界。
在之前提过zygote的socket的客户端可以是AMS,下一节我们分析如何开启一个Activity。
标签:
原文地址:http://www.cnblogs.com/hongguang-kim/p/4815351.html