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

来源:互联网 发布:学mysql还是sql server 编辑:程序博客网 时间:2024/05/22 10:41

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 */    }

梳理一下流程

流程图

原创粉丝点击