前言
Android系统中,所有的应用程序以及SystemServer都是由Zygote进程孕育(fork)出来的。接上文,上文介绍从Native世界进入了Java世界。而且java世界的大门就是ZygtoeInit.java。这次我们看ZygtoeInit中处理了哪些功能。
Android P
正文
涉及文件
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java frameworks\base\core\java\com\android\internal\os\ZygoteServer.java frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java frameworks\base\core\java\com\android\internal\os\RuntimeInit.java frameworks\base\core\jni\com_android_internal_os_Zygote.cpp frameworks\base\core\jni\com_android_internal_os_ZygoteInit.cpp
接上一篇《Zygote的启动之一app_main》,启动了com.android.internal.os.ZygoteInit进入了Java的世界,
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
args中的参数
{"start-system-server", "--abi-list=arm64-v8a", "--socket-name=zygote", "--enable-lazy-preload"}
进入ZygoteInit.java世界,启动的依旧是main()函数。
public static void main(String argv[]) { //[1]创建ZygoteServer ZygoteServer zygoteServer = new ZygoteServer(); final Runnable caller; try { for (int i = 1; i < argv.length; i++) { //是否有start-system-server参数,有就需要启动startSystemServer if ("start-system-server".equals(argv[i])) { //是否启动SystemServer startSystemServer = true; } else if ("--enable-lazy-preload".equals(argv[i])) { //是否延迟加载 enableLazyPreload = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { //32位 --abi-list=armeabi-v7a,armeabi //64位 --abi-list=arm64-v8a abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { //设置socket名 socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } //[2]注册socket zygoteServer.registerServerSocketFromEnv(socketName); //懒惰预加载,enableLazyPreload=true; if (!enableLazyPreload) { //这里暂时不走 preload(bootTimingsTraceLog); } else { Zygote.resetNicePriority(); } //[3]提前加载Resources preloadResources(); //提前加载文本Resources preloadTextResources(); //主动GC gcAndFinalize(); //我这64位时startSystemServer= true if (startSystemServer) { //[4]创建SystemServer Runnable r = forkSystemServer(abiList, socketName, zygoteServer); if (r != null) { r.run(); return; } } //[5]循环中。对于zygote不会退出,至于fork的子进程,是会退出的 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { throw ex; } finally { //关闭socket zygoteServer.closeServerSocket(); } if (caller != null) { caller.run(); } }
上面主要是如下功能:
-
创建ZygoteServer
-
注册socket
-
预加载资源
-
创建SystemServer
-
runSelectLoop()一直循环处理
下面就简单的走一下流程。
创建ZygoteServer
ZygoteServer zygoteServer = new ZygoteServer();
功能很简单,就是创建ZygoteServer对象,后面需要。
注册socket
zygoteServer.registerServerSocketFromEnv(socketName);
也就是处理功能都是ZygoteServer类。
socketName就是之前init.zygote64_32.rc中配置的。
64位socketName:zygote 32位socketName:zygote_secondary
就是注册了对应的socket,后面用于通信
void registerServerSocketFromEnv(String socketName) { if (mServerSocket == null) { //略 FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); //创建mServerSocket mServerSocket = new LocalServerSocket(fd); mCloseSocketFd = true; } }
预加载资源
//enableLazyPreload= true if (!enableLazyPreload) { //暂时不走这里,后面会加载 preload(bootTimingsTraceLog); } else { Zygote.resetNicePriority(); } //提前加载Resources preloadResources(); //提前加载文本Resources preloadTextResources();
提前加载系统相关的资源,这也是为啥开发中推荐优先用系统资源文件。
预加载的资源是存在framework-res.apk中。
forkSystemServer()
if (startSystemServer) { // fork SystemServer,并返回一个 Runnable Runnable r = forkSystemServer(abiList, socketName, zygoteServer); if (r != null) { r.run(); return; } }
这里是创建出SystemServer进程,然后后面找到main()入口函数,进行启动SystemServer.java
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer){ //略 //配置uid,gid,group等参数 String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", //进程名 "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", //启动类 }; int pid; try { //参数转换 parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); //默认为false boolean profileSystemServer = SystemProperties.getBoolean( "dalvik.vm.profilesystemserver", false); //fork一个进程,就是创建SystemServer pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.runtimeFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } //子进程 if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } //关闭子进程的socket zygoteServer.closeServerSocket(); //处理SYstemServer进程 return handleSystemServerProcess(parsedArgs); } return null; }
进入handleSystemServerProcess
handleSystemServerProcess()
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { if (parsedArgs.niceName != null) { //设置进程名为system_server Process.setArgV0(parsedArgs.niceName); } //加载SystemServer类的路径 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); //systemServerClasspath不为空 if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); //profileSystemServer = false boolean profileSystemServer = SystemProperties.getBoolean( "dalvik.vm.profilesystemserver", false); //略 } //parsedArgs.invokeWith = null if (parsedArgs.invokeWith != null) { //不走这 } else { ClassLoader cl = null; if (systemServerClasspath != null) { //创建ClassLoader cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } //进入ZygoteInit.zygoteInit() return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } }
systemServerClasspath存储的内容
/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar:/system/framework/car-frameworks-service.jar
zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){ //略 //native方法 ZygoteInit.nativeZygoteInit(); //进入applicationInit,返回Runnable return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }
applicationInit()
此时进入了RuntimeInit.java中,我们看applicationInit()
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) { //略 return findStaticMain(args.startClass, args.startArgs, classLoader); }
findStaticMain()
看名字就是找到类的启动入口。
根据前面,知道className传入的是com.android.server.SystemServer
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) { Class<?> cl; try { //加载com.android.server.SystemServer类 cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { } Method m; try { //查找main函数 m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { } int modifiers = m.getModifiers(); //判断是否有static和public修饰 if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException( "Main method is not public and static on " + className); } //MethodAndArgsCaller就是一个Runnable return new MethodAndArgsCaller(m, argv); }
最终就创建的一个Runnable。
MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable { private final Method mMethod; private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { //Method = com.android.server.SystemServer的main函数 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { //略 } } }
上面我们知道,fork出SystemServer之后,进行了null判断,然后启动了run()
这里用了反射
# Method = com.android.server.SystemServer的main函数 mMethod.invoke(null, new Object[] { mArgs });
到这里就算启动了com.android.server.SystemServer,并进入了main()。
疑惑
if (startSystemServer) { // fork SystemServer,并返回一个 Runnable Runnable r = forkSystemServer(abiList, socketName, zygoteServer); if (r != null) { //这里进入了MethodAndArgsCaller的run() r.run(); //哈哈这里return return; } }
上面fork出SystemServer后,r不为null,也就是执行了下面代码
if (r != null) { r.run(); return; }
这里竟然直接return了,那后面代码不执行?
其实不是,这个就需要看Linux中的fork的原理。上面return的只是子进程(SystemServer进程)程序,而父类进程还是会继续往下执行。也就是进入了runSelectLoop()
runSelectLoop()
//循环中。 caller = zygoteServer.runSelectLoop(abiList);
对于父进程,也就是Zygote的会进入循环中;对于子进程SystemServer在上面会return,其他子进程,会返回caller,然后退出。
Runnable runSelectLoop(String abiList) { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); //mServerSocket是之前创建的socket fds.add(mServerSocket.getFileDescriptor()); peers.add(null); //死循环 while (true) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; for (int i = 0; i < pollFds.length; ++i) { pollFds[i] = new StructPollfd(); pollFds[i].fd = fds.get(i); pollFds[i].events = (short) POLLIN; } for (int i = pollFds.length - 1; i >= 0; --i) { //采用I/O多路复用机制,当客户端发出连接请求或者数据处理请求时,则执行continue if ((pollFds[i].revents & POLLIN) == 0) { continue; } if (i == 0) { //有socket客户端连接上,创建一个新的ZygoteConnection ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); //添加socket的描述符 fds.add(newPeer.getFileDesciptor()); } else { try { //客户端发送了请求 ZygoteConnection connection = peers.get(i); //这里创建了一个Runnable,是不是子进程,这里会设置 final Runnable command = connection.processOneCommand(this); if (mIsForkChild) { //如果在子进程,就返回Runnable return command; } else { //判断是否需要关闭socket if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(i); fds.remove(i); } } } } } } }
runSelectLoop()是个死循环,也就是Zygote是一直存在并处理对应事物的。主要做了如下事
-
添加之前创建的socket并获取请求消息
-
进入死循环读取请求消息
-
i == 0时,有新客户端,创建新的ZygoteConnection
-
i != 0时,处理客户端发送的请求,如果是子进程,就返回Runnable
processOneCommand()
下面就介绍一下,当收到新的子进程创建流程。
Runnable processOneCommand(ZygoteServer zygoteServer) { try { //从socket读取命令 args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { throw new IllegalStateException("IOException on command socket", ex); } //如果没有读取到命令,socket可能断了, if (args == null) { isEof = true; return null; } //创建Arguments对象,这里会解析args中的命令 parsedArgs = new Arguments(args); //根据参数值进行处理 if (parsedArgs.abiListQuery) { handleAbiListQuery(); return null; } //handlePreload也就是之前没有预加载的 if (parsedArgs.preloadDefault) { handlePreload(); return null; } //略 // fork进程 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote, parsedArgs.instructionSet, parsedArgs.appDataDir); try { if (pid == 0) {//如果是子线程,进入这里 zygoteServer.setForkChild(); zygoteServer.closeServerSocket(); IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; //handleChildProc return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.startChildZygote); } else { //如果是父进程,走这里 IoUtils.closeQuietly(childPipeFd); childPipeFd = null; handleParentProc(pid, descriptors, serverPipeFd); return null; } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } }
这里主要如下工作
-
readArgumentList()从socket读取命令
-
Arguments解析读取的命令并执行对应的功能
-
根据parsedArgs的信息进行fork进程
-
处理子进程并返回Runnable
readArgumentList()
主要是从socket中读取命令
private String[] readArgumentList()throws IOException { int argc; try { //socket读取一行命名 String s = mSocketReader.readLine(); if (s == null) { return null; } argc = Integer.parseInt(s); } catch (NumberFormatException ex) { Log.e(TAG, "invalid Zygote wire format: non-int at argc"); throw new IOException("invalid wire format"); } if (argc > MAX_ZYGOTE_ARGC) { throw new IOException("max arg count exceeded"); } String[] result = new String[argc]; for (int i = 0; i < argc; i++) { //读取出所有的命令 result[i] = mSocketReader.readLine(); if (result[i] == null) { throw new IOException("truncated request"); } } return result; }
Arguments
//创建Arguments对象,这里会解析args中的命令 parsedArgs = new Arguments(args);
Arguments(String args[]) throws IllegalArgumentException { parseArgs(args); }
最终是调用parseArgs()解析命令,很长,略过,就是对命令解析并对parsedArgs的属性进行赋值。
handlePreload()
根据之前parsedArgs中解析的命令,执行对应的功能。我这里以handlePreload()为例。
if (parsedArgs.preloadDefault) { handlePreload(); //返回null,也就是处理完后就不会继续执行后面的代码 return null; }
private void handlePreload() {= try { //判断是否有预加载过,如果有就调过,没有就执行preload() if (isPreloadComplete()) { mSocketOutStream.writeInt(1); } else { preload(); mSocketOutStream.writeInt(0); } } catch (IOException ioe) { throw new IllegalStateException("Error writing to command socket", ioe); } }
isPreloadComplete()返回true的前提是有执行过preload()中调用的ZygoteInit.preload(),后面会看到。
preload()
protected void preload() { ZygoteInit.lazyPreload(); }
哈哈 进入ZygoteInit.java
ZygoteInit.lazyPreload()
public static void lazyPreload() { Preconditions.checkState(!sPreloadComplete); preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK)); }
ZygoteInit.preload()
static void preload(TimingsTraceLog bootTimingsTraceLog) { //只做了一件事,preloadClasses preloadClasses(); //sPreloadComplete这里赋值为true sPreloadComplete = true; }
preloadClasses()看函数名就名,预加载类,就是提前加载一些类而已。
forkAndSpecialize()
这根据中parsedArgs的信息,然后fork一个新的进程。我们关注pid,不关心怎么fork。
如果pid=0,表示子进程,走处理子进程流程,返回Runnable
如果pid!=0,表示父进程,走处理父进程的流程,返回null
handleChildProc()
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) { //关闭socket通信 closeSocket(); //设置进程名 if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } //一般这里为invokeWith = null //除非parsedArgs解析socket命令行中有对应的命令,略过,看下面 if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), pipeFd, parsedArgs.remainingArgs); throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { //isZygote = false,就是parsedArgs.startChildZygote if (!isZygote) { //走这里。又回到了ZygoteInit类 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } } }
ZygoteInit.zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { //RuntimeInit初始化相关 RuntimeInit.redirectLogStreams(); RuntimeInit.commonInit(); //native方法 ZygoteInit.nativeZygoteInit(); //执行applicationInit return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }
zygoteInit()也是不干活的,真正处理进入RuntimeInit
RuntimeInit.applicationInit()
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) { nativeSetExitWithoutCleanup(true); VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //找到static的main入口 return findStaticMain(args.startClass, args.startArgs, classLoader); }
也是不干活的,哈哈,这个跟上面启动com.android.server.SystemServer是找到static的mian入口一样的流程了?
最后都一样,findStaticMain()返回Runnable,然后启动run(),通过反射直接进入main()入口,也就是算启动了进程。
到这里,就基本走完了一圈,zygote也一直循环,等待着新的命令进行fork出新的进程。
参考文章
-
《》
-
《深入理解Android卷1(邓凡平)》
-
《》
-
《》