System_server 与/dev/socket/zygote
来源:互联网 发布:中国房地产数据统计 编辑:程序博客网 时间:2024/05/16 05:46
system_server除了在进程刚创建的时候通过/dev/socket/zygote,连接一下zygote 之后,只有在打开apk需要fork 进程时,会再次连接zygote 进程。
system_server 在创建是首次连接zygote, 是因为zygote 进程需要保存system_server的ZygoteConnection对象,为了之后读取system_server 传入参数,加快效率,可以看:
http://blog.csdn.net/xiaolli/article/details/72834220
system_server 创建进程
apk 端创建新的进程一般都是通过:activity、service、contentProvider、broadcast这几个,
他们最后都是会走到ams 的startProcessLocked
方法
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs);}
在startProcessLocked
方法内会去调用Process.start
方法去fork进程,并将结果返回, entryPoint
fork进程的入口类,一般为android.app.ActivityThread
,好像只有通过startIsolatedProcess 方法才可以指定为其他的类调用方式为:
LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess(***)
app.processName
fork 进程的进程名 entryPointArgs
入口类的,参数
Process.start
方法:
public static final ProcessStartResult start(final String processClass, final String niceName,int uid, int gid, int[] gids,int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String[] zygoteArgs) { return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, zygoteArgs );}private static ProcessStartResult startViaZygote(final String processClass,final String niceName, final int uid, final int gid,final int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi, String instructionSet, String appDataDir, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { ArrayList<String> argsForZygote = new ArrayList<String>(); argsForZygote.add("--runtime-args"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) { argsForZygote.add("--enable-jni-logging"); } argsForZygote.add(processClass); if (extraArgs != null) { for (String arg : extraArgs) { argsForZygote.add(arg); } } return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } }
由以上代码可知,Process.start
会去调用其自身的 startViaZygote
方法,
在startViaZygote
方法中,会根据参数添加对应的头(类似”–setuid=”)后加入argsForZygote 中,以便在zygote 端进行解析。
此处是将 入口类的参数放入了 argsForZygote 最末尾
入口类放入了, 参数之前。
之后调用openZygoteSocketIfNeeded
方法连接zygote
调用zygoteSendArgsAndGetResult
方法将参数通过socket 传给zygote,并获取结果
openZygoteSocketIfNeeded
去连接socket
public static final String ZYGOTE_SOCKET = "zygote";private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET); return primaryZygoteState;}
zygoteSendArgsAndGetResult
去发送参数,并等待获取结果
private static ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args)throws ZygoteStartFailedEx { final BufferedWriter writer = zygoteState.writer; final DataInputStream inputStream = zygoteState.inputStream; //将数据写入socket 对应的流中 writer.write(Integer.toString(args.size())); writer.newLine(); for (int i = 0; i < sz; i++) { String arg = args.get(i); writer.write(arg); writer.newLine(); } writer.flush(); //等待socket那端,并将结果回传过来。 ProcessStartResult result = new ProcessStartResult(); result.pid = inputStream.readInt(); result.usingWrapper = inputStream.readBoolean(); return result;}
之后就会走到zygote,去进行后续的操作,
Zygote fork 进程
在Process.java 方法中连接/dev/socket/zygote,并传数据给此socket,那么他的服务端,会接收到数据进行后续操作
ZygoteInit.java 类中
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { while (true) { Os.poll(pollFds, -1); //等待有人连接 /dev/socket/zygote if (i == 0) { //system_server进程在创建时第一次与Zygote 连接,将system_server 端的ZygoteConnection 对象存储下来。 } else { //后续ams 中需要fork 进程时,会调用system_server进程的ZygoteConnection类的 runOnce 方法,读取参数,fork进程,进行后续操作 boolean done = peers.get(i).runOnce(); } }}
ZygoteConnection.java
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; //获取ams 中传入的参数 args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); int pid = -1; FileDescriptor childPipeFd = null; FileDescriptor serverPipeFd = null; try { //解析ams 中传入的参数,并将解析结果赋值给Arguments 对象 parsedArgs = new Arguments(args); FileDescriptor fd = mSocket.getFileDescriptor(); //去fork,apk进程 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, parsedArgs.appDataDir); } catch (ErrnoException ex) {} try { if (pid == 0) { // in child IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; //如果是fork 出来的进程,在handleChildProc 中进行后续操作,加载入口类,**** handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); return true; } else { //如果是zygote进程,在handleParentProc 方法中将结果 通过socket 传给ams, return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } }
handleParentProc
的操作比较简单,将创建进程的pid传输给了 ams,之后ams那端将不再等待,会获取传输经过,并将ProcessStartResult 返回
private static ProcessStartResult zygoteSendArgsAndGetResult ****** ProcessStartResult result = new ProcessStartResult(); //获取zygote 传过来的pid,赋值给ProcessStartResult,然后将对象返回 result.pid = inputStream.readInt(); result.usingWrapper = inputStream.readBoolean(); return result;}
handleChildProc
方法的执行,是在新的进程中,此进程即作为apk的运行进程:
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr){ if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), pipeFd, parsedArgs.remainingArgs); } else { RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } }}
在此handleChildProc
方法中,一般都走的是RuntimeInit.zygoteInit,好像很少走 WrapperInit.execApplication
parsedArgs.remainingArgs: String 数组,
数组的第0个元素为 入口类,
其他的元素为 入口类的 参数。
对应Process.startViaZygote
中写入时的情景。
在之后会在 RuntimeInit.zygoteInit
中进行一系列的调用,最后会去反射调用入口类的 main 方法,并将参数传入。
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { //从定向log,将System.out、System.err,从定向到Android log 中 redirectLogStreams(); //设置默认的异常处理函数,当进程异常crash时,会走UncaughtHandler的uncaughtException 方法。 commonInit(); nativeZygoteInit(); //反射调用入口类的main方法并将参数传入。 applicationInit(targetSdkVersion, argv, classLoader);}private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) final Arguments args = new Arguments(argv); invokeStaticMain(args.startClass, args.startArgs, classLoader);}//获取入口类的class,与其方法 method, 将其与参数赋值给 ZygoteInit.MethodAndArgsCaller ,然后将异常抛出去private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader){ Class<?> cl = Class.forName(className, true, classLoader); Method m = cl.getMethod("main", new Class[] { String[].class }); throw new ZygoteInit.MethodAndArgsCaller(m, argv);}
在invokeStaticMain 方法中,获取到入口的类对象,与main 方法对象,然后构造出一个异常类,之后将异常类抛了出去,此异常会在ZygoteInit.java
中被捕获:
public static void main(String argv[]) { String socketName = "zygote"; try { runSelectLoop(abiList); } catch (MethodAndArgsCaller caller) { caller.run(); //此处捕获到异常,会反射调用MethodAndArgsCaller内部参数标识入口类。 }}
public static class MethodAndArgsCaller extends Exception implements Runnable { private final Method mMethod; //入口类的main 方法 private final String[] mArgs; //入口类的参数 //在invokeStaticMain 赋值 public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } //在ZygoteInit 中,捕获异常并调用 public void run() { try{ mMethod.invoke(null, new Object[] { mArgs }); //到此就在新进程中执行 android.app.ActivityThread 的main 方法。 } catch (InvocationTargetException ex) { throw new RuntimeException(ex); } } } =
- System_server 与/dev/socket/zygote
- Zygote 与/dev/socket/zygote
- System_Server与Zygote共存亡
- zygote-->system_server
- zygote-->system_server
- Android之system_server与zygote之作用
- Android之system_server与zygote之作用
- Android之system_server与zygote之作用
- Android之system_server与zygote之作用
- Android之system_server与zygote之作用
- Android之system_server与zygote之作用
- zygote system_server的启动
- zygote和system_server分析
- 系统入门(12):Android之system_server与zygote之作用
- system_server socket 泄露
- zygote
- Zygote
- ZYgote
- Ureport 使用注意
- CSDN精选Android开发博客
- jQuery来了--尺寸,返回/设置元素的宽高度
- 【SVN】Eclipse中使用Svn上传和下载代码
- ElasticSearch 模糊匹配查询
- System_server 与/dev/socket/zygote
- 如何在ImagePickerController中只显示图片或者视频
- 正则表达式匹配中文
- Hystrix 使用与分析
- ListBox设置AddString排序
- git help 用chrome打开
- 袁萌:高考恢复40年有感
- 关于spring+hibernate的FlushMode的记录
- 【编程素质】算法-矩阵连乘问题(枚举法、备忘录法、动态规划)