Android源码(1) --- Zygote进程启动流程

Zygote进程简介

什么是Zygote进程? Zygote进程 是整个Android系统的根进程,包括SystemServer进程和所有应用进程在内都是通过Zygote进程 fork 出来的。Zygote进程则是通过Linux系统init进程启动。

  • 启动顺序: Linux系统init进程 --> Zygote进程 --> SystemServer进程 --> Application 进程
  • init进程:Android系统第一个进程,也是linux的根进程,主要用于初始化各种文件系统,输入输出系统,log系统等等设备相关联的初始化
  • Zygote进程:Android系统的根进城,用于fork除SystemServer进程和各种应用进程
  • SystemServer进程 --> 启动ActivityManagerService,WindowManagerService,PowerManagerService等等各项服务
  • Application 进程: App 应用进程

源码分析(Android 6.0)

  • 1.从ZygoteInit main()方法中开始看。
  public static void main(String argv[]) {
        try {
            RuntimeInit.enableDdms();
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }

            registerZygoteSocket(socketName);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gcAndFinalize();

            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false);

            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            Log.i(TAG, "Accepting command socket connections");
            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

  • 从上面可以看到主要做了哪几件事

    • 1.1 enableDdms() 设置DDMS可用

    • 1.2 for 循环,解析是否需要启动SystemService进程;获取abi列表;获取socket连接名称

    • 1.3 registerZygoteSocket(String socketName) 为Zygote 进程注册socket;(PS:Android中进程间通都是用Binder,但是有一个例外,SystemService进程与Zygote进程之间是通过Socket的方式进行通讯的)

       private static void registerZygoteSocket(String socketName) {
          if (sServerSocket == null) {
              int fileDesc;
              final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
              try {
                  String env = System.getenv(fullSocketName);
                  fileDesc = Integer.parseInt(env);
              } catch (RuntimeException ex) {
                  throw new RuntimeException(fullSocketName + " unset or invalid", ex);
              }
      
              try {
                  FileDescriptor fd = new FileDescriptor();
                  fd.setInt$(fileDesc);
                  sServerSocket = new LocalServerSocket(fd);
              } catch (IOException ex) {
                  throw new RuntimeException(
                          "Error binding to local socket '" + fileDesc + "'", ex);
              }
          }
      }
      
    • 1.4 preload(),可以看到
      preloadClasses 初始化Zygote所需的类
      preloadResources 初始化通用系统资源
      preloadOpenGL 初始化OpenGL
      preloadSharedLibraries 初始化 shared libraries
      preloadTextResources 初始化文字资源
      prepareWebViewInZygote 初始化WebView(必须是Zygote进程)

      static void preload() {
              Log.d(TAG, "begin preload");
              preloadClasses();
              preloadResources();
              preloadOpenGL();
              preloadSharedLibraries();
              preloadTextResources();
              // Ask the WebViewFactory to do any initialization that must run in the zygote process,
              // for memory sharing purposes.
              WebViewFactory.prepareWebViewInZygote();
              Log.d(TAG, "end preload");
          }
      
    • 1.5 SamplingProfilerIntegration.writeZygoteSnapshot() 存储一下zygote进程快照
      gcAndFinalize() fork之前调用下系统GC

    • 1.6 startSystemServer(abiList, socketName),接下来就是fork SystemServer进程了
      通过Zygote.forkSystemServe() fork 出SystemServer进程

    • 1.7 关闭Socket
      handleSystemServerProcess 当fork出SystemServer后关闭socket

    private static boolean startSystemServer(String abiList, String socketName)
                            throws MethodAndArgsCaller, RuntimeException {
                        long capabilities = posixCapabilitiesAsBits(
                            OsConstants.CAP_BLOCK_SUSPEND,
                            OsConstants.CAP_KILL,
                            OsConstants.CAP_NET_ADMIN,
                            OsConstants.CAP_NET_BIND_SERVICE,
                            OsConstants.CAP_NET_BROADCAST,
                            OsConstants.CAP_NET_RAW,
                            OsConstants.CAP_SYS_MODULE,
                            OsConstants.CAP_SYS_NICE,
                            OsConstants.CAP_SYS_RESOURCE,
                            OsConstants.CAP_SYS_TIME,
                            OsConstants.CAP_SYS_TTY_CONFIG
                        );
                        /* Hardcoded command line to start the system server */
                        String args[] = {
                            "--setuid=1000",
                            "--setgid=1000",
                            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
                            "--capabilities=" + capabilities + "," + capabilities,
                            "--nice-name=system_server",
                            "--runtime-args",
                            "com.android.server.SystemServer",
                        };
                        ZygoteConnection.Arguments parsedArgs = null;
                
                        int pid;
                
                        try {
                            parsedArgs = new ZygoteConnection.Arguments(args);
                            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
                            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
                
                            /* Request to fork the system server process */
                            pid = Zygote.forkSystemServer(
                                    parsedArgs.uid, parsedArgs.gid,
                                    parsedArgs.gids,
                                    parsedArgs.debugFlags,
                                    null,
                                    parsedArgs.permittedCapabilities,
                                    parsedArgs.effectiveCapabilities);
                        } catch (IllegalArgumentException ex) {
                            throw new RuntimeException(ex);
                        }
                
                        /* For child process */
                        if (pid == 0) {
                            if (hasSecondZygote(abiList)) {
                                waitForSecondaryZygote(socketName);
                            }
                
                            handleSystemServerProcess(parsedArgs);
                        }
                
                        return true;
                    }
    
    
        /**
         * Finish remaining work for the newly forked system server process.
         */
        private static void handleSystemServerProcess(
                ZygoteConnection.Arguments parsedArgs)
                throws ZygoteInit.MethodAndArgsCaller {
    
            closeServerSocket();
    
            // set umask to 0077 so new files and directories will default to owner-only permissions.
            Os.umask(S_IRWXG | S_IRWXO);
    
            if (parsedArgs.niceName != null) {
                Process.setArgV0(parsedArgs.niceName);
            }
    
            final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
            if (systemServerClasspath != null) {
                performSystemServerDexOpt(systemServerClasspath);
            }
    
            if (parsedArgs.invokeWith != null) {
                String[] args = parsedArgs.remainingArgs;
                // If we have a non-null system server class path, we'll have to duplicate the
                // existing arguments and append the classpath to it. ART will handle the classpath
                // correctly when we exec a new process.
                if (systemServerClasspath != null) {
                    String[] amendedArgs = new String[args.length + 2];
                    amendedArgs[0] = "-cp";
                    amendedArgs[1] = systemServerClasspath;
                    System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
                }
    
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        VMRuntime.getCurrentInstructionSet(), null, args);
            } else {
                ClassLoader cl = null;
                if (systemServerClasspath != null) {
                    cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                    Thread.currentThread().setContextClassLoader(cl);
                }
    
                /*
                 * Pass the remaining arguments to SystemServer.
                 */
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
            }
    
            /* should never reach here */
        }
    

### 梳理一下流程
![流程图](https://github.com/jfson/ImgResource/blob/master/13.png?raw=true)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容