Android应用程序进程启动过程的源代码分析(2)
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- public class ZygoteInit {
- ......
- /**
- * Runs the zygote process's select loop. Accepts new connections as
- * they happen, and reads commands from connections one spawn-request's
- * worth at a time.
- *
- * @throws MethodAndArgsCaller in a child process when a main() should
- * be executed.
- */
- private static void runSelectLoopMode() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList();
- ArrayList<ZygoteConnection> peers = new ArrayList();
- FileDescriptor[] fdArray = new FileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- peers.add(null);
- int loopCount = GC_LOOP_COUNT;
- while (true) {
- int index;
- /*
- * Call gc() before we block in select().
- * It's work that has to be done anyway, and it's better
- * to avoid making every child do it. It will also
- * madvise() any free memory as a side-effect.
- *
- * Don't call it every time, because walking the entire
- * heap is a lot of overhead to free a few hundred bytes.
- */
- if (loopCount <= 0) {
- gc();
- loopCount = GC_LOOP_COUNT;
- } else {
- loopCount--;
- }
- try {
- fdArray = fds.toArray(fdArray);
- index = selectReadable(fdArray);
- } catch (IOException ex) {
- throw new RuntimeException("Error in select()", ex);
- }
- if (index < 0) {
- throw new RuntimeException("Error in select()");
- } else if (index == 0) {
- ZygoteConnection newPeer = acceptCommandPeer();
- peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
- } else {
- boolean done;
- done = peers.get(index).runOnce();
- if (done) {
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
- ......
- }
- done = peers.get(index).runOnce();
- class ZygoteConnection {
- ......
- boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
- String args[];
- Arguments parsedArgs = null;
- FileDescriptor[] descriptors;
- try {
- args = readArgumentList();
- descriptors = mSocket.getAncillaryFileDescriptors();
- } catch (IOException ex) {
- ......
- return true;
- }
- ......
- /** the stderr of the most recent request, if avail */
- PrintStream newStderr = null;
- if (descriptors != null && descriptors.length >= 3) {
- newStderr = new PrintStream(
- new FileOutputStream(descriptors[2]));
- }
- int pid;
- try {
- parsedArgs = new Arguments(args);
- applyUidSecurityPolicy(parsedArgs, peer);
- applyDebuggerSecurityPolicy(parsedArgs);
- applyRlimitSecurityPolicy(parsedArgs, peer);
- applyCapabilitiesSecurityPolicy(parsedArgs, peer);
- int[][] rlimits = null;
- if (parsedArgs.rlimits != null) {
- rlimits = parsedArgs.rlimits.toArray(intArray2d);
- }
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
- } catch (IllegalArgumentException ex) {
- ......
- } catch (ZygoteSecurityException ex) {
- ......
- }
- if (pid == 0) {
- // in child
- handleChildProc(parsedArgs, descriptors, newStderr);
- // should never happen
- return true;
- } else { /* pid != 0 */
- // in parent...pid of < 0 means failure
- return handleParentProc(pid, descriptors, parsedArgs);
- }
- }
- ......
- }
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
- if (pid == 0) {
- // in child
- handleChildProc(parsedArgs, descriptors, newStderr);
- // should never happen
- return true;
- } else { /* pid != 0 */
- ......
- }
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
- class ZygoteConnection {
- ......
- private void handleChildProc(Arguments parsedArgs,
- FileDescriptor[] descriptors, PrintStream newStderr)
- throws ZygoteInit.MethodAndArgsCaller {
- ......
- if (parsedArgs.runtimeInit) {
- RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
- } else {
- ......
- }
- }
- ......
- }
- public class RuntimeInit {
- ......
- public static final void zygoteInit(String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- // TODO: Doing this here works, but it seems kind of arbitrary. Find
- // a better place. The goal is to set it up for applications, but not
- // tools like am.
- System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
- System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
- commonInit();
- zygoteInitNative();
- int curArg = 0;
- for ( /* curArg */ ; curArg < argv.length; curArg++) {
- String arg = argv[curArg];
- if (arg.equals("--")) {
- curArg++;
- break;
- } else if (!arg.startsWith("--")) {
- break;
- } else if (arg.startsWith("--nice-name=")) {
- String niceName = arg.substring(arg.indexOf('=') + 1);
- Process.setArgV0(niceName);
- }
- }
- if (curArg == argv.length) {
- Slog.e(TAG, "Missing classname argument to RuntimeInit!");
- // let the process exit
- return;
- }
- // Remaining arguments are passed to the start class's static main
- String startClass = argv[curArg++];
- String[] startArgs = new String[argv.length - curArg];
- System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
- invokeStaticMain(startClass, startArgs);
- }
- ......
- }
- public class RuntimeInit {
- ......
- public static final native void zygoteInitNative();
- ......
- }
- static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
- {
- gCurRuntime->onZygoteInit();
- }
- static AndroidRuntime* gCurRuntime = NULL;
- AndroidRuntime::AndroidRuntime()
- {
- ......
- assert(gCurRuntime == NULL); // one per process
- gCurRuntime = this;
- }
- int main(int argc, const char* const argv[])
- {
- ......
- AppRuntime runtime;
- ......
- }
- class AppRuntime : public AndroidRuntime
- {
- ......
- };
Android应用程序进程启动过程的源代码分析(2)相关推荐
- Android应用程序进程启动过程的源代码分析(1)
Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实 ...
- Android应用程序进程启动过程
相关文章 Android系统架构与系统源码目录 Android系统启动流程(一)解析init进程启动过程 Android系统启动流程(二)解析Zygote进程启动过程 Android系统启动流程(三) ...
- Android系统进程Zygote启动过程的源代码分析(3)
Step 5. ZygoteInit.startSystemServer 这个函数定义在frameworks/base/core/java/com/android/internal/os ...
- Android系统进程Zygote启动过程的源代码分析
原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口 ...
- android 启动app过程,应用程序进程启动过程
原标题:应用程序进程启动过程 作者:慕涵盛华 链接:https://www.jianshu.com/p/b158615cc2ad 一.背景 首先注意的是:这里要说的是应用程序进程的启动过程,而不是应用 ...
- 从源码角度看Android系统SystemServer进程启动过程
SystemServer进程是由Zygote进程fork生成,进程名为system_server,主要用于创建系统服务. 备注:本文将结合Android8.0的源码看SystemServer进程的启动 ...
- 从源码角度看Android系统Zygote进程启动过程
在Android系统中,DVM.ART.应用程序进程和SystemServer进程都是由Zygote进程创建的,因此Zygote又称为"孵化器".它是通过fork的形式来创建应用程 ...
- 应用程序进程启动过程
--摘自<Android进阶解密> 1.AMS在启动应用程序时会检查者应用程序需要的应用进程是否存在,不存在就会请求Zygote进程启动需要的应用程序进程 2.Zygote的Java框架层 ...
- [日更-2019.4.26、27、28] cm-14.1 Android系统启动过程分析(四)-应用程序进程启动过程...
2019独角兽企业重金招聘Python工程师标准>>> 声明 前阶段在项目中涉及到了Android系统定制任务,Android系统定制前提要知道Android系统是如何启动的: 本文 ...
最新文章
- linux死锁检测的一种思路【转】
- Windows10 JDK9安装及配置环境变量与Eclipse安装
- R12客户表结构分析
- 完整的中英文词频统计
- MapReduce基础开发之一词汇统计和排序(wordcount)
- 客户要求ASP.NET Core API返回特定格式,怎么办?(续)
- ABP入门系列(10)——扩展AbpSession
- 揭秘2019双11背后的云网络 – 双11网络架构和洛神系统
- 物联网入门学什么开发板_物联网入门:如何构建DIY Blynk板
- java数组r.id_Android HelloViews Spinner教程R.id和R.array无法解析
- 使用分治思想求解最大子序列
- 麦子学院深度学习进阶课程题目纲要
- win10系统镜像文件iso下载教程
- 碎片化学习和系统化学习的对比
- day12摇色子游戏--笔记
- Centos使用chrony做时间同步
- python句柄无效_作为Windows服务运行的Python:OSError:[WinError 6]句柄无效
- Ubuntu的ldconfig详解(解决*.so不是符号连接)
- MySQL、PostgreSQL、NoSQL、CynosDB,究竟谁是数据库王者?
- 初级程序员与高级程序员