《android framework常用api源码分析》之Zygote进程

版权声明:转载时请标明出处。https://blog.csdn.net/mhhyoucom https://blog.csdn.net/mhhyoucom/article/details/78782437

《android framework常用api源码分析》android生态在中国已经发展非常庞大了,一方面是因为手机移动端的覆盖,另一方面是从事android开发的人也月来越多。那么用人单位对android要求也变了,对android不仅要熟练使用而且要懂得原理。而就程序员自身阅读源码有什么那些?这里我通过自己理解归纳了一下。

  1. 提高程序执行效率,正确理解api可以高效使用,优化内存和执行效率。

  2. 避免八阿哥强势逆袭,android开发同学都知道android找bug比较麻烦,尤其是一下jni底层调用错误信息不够明确地方更加难找。

  3. 帮助自己写出优雅的代码,开发需要规范,而源码中有很多优秀的谷歌规范。

  4. 优秀的设计模式,帮助自己提升程序造诣。

  5. 黑科技,通过反射高一些api不能够达到的功能,例如插件化、热更新。

上面是简单个人理解,有更多补充欢迎留言。所以这里准备出一个系列的文章来分析android framework api, 这些文章也是来自整理于网络,所以要感谢那些具有分享精神的大神们。

文章目录:

  1. apk 打包过程解析。
  2. handler 消息机制。
  3. AsyncTask 异步任务。
  4. HandlerThread handler线程。
  5. IntentService意图服务。
  6. Zygote进程。
  7. SystemServer进程。
  8. Launcher 程序。
  9. app 进程启动流程。
  10. 系统app启动安装流程。
  11. app应用安装流程。
  12. Activity启动流程。
  13. LruCache内存缓存

Zygote进程是什么?
Zygote进程是android系统启动的第一个进程(不包括kernel层次的init进程),是所有的android进程的父进程,是一个根进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。Zygote(孵化)进程相当于是android系统的根进程,后面所有的进程都是通过这个进程fork出来的,而Zygote进程则是通过linux系统的init进程启动的,也就是说,android系统中各种进程的启动方式

init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程

  • init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;

  • Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;

  • SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;

  • 各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;

本文主要介绍一下Zygote进程的启动流程,关于SystenServer进程和各种应用进程的启动方式会在以后的文章中介绍。

init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法,因此我们这里看一下该方法的具体实现(基于android23源码);

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;
        }
    }
  • 第一行主要是调用enableDdms(),设置DDMS可用,可以发现DDMS启动的时机还是比较早的,在整个Zygote进程刚刚开始要启动额时候就设置可用了。

  • 下面的循环主要是解析main方法的参数获取是否需要启动SystemService进程,获取abi列表,获取scoket连接名称
    (这里需要注意的是:android系统中进程之间通讯的方式是Binder,但是有一个例外是SystemService进程与Zygote进程之间是通过Socket的方式进行通讯的)

  • 然后调用registerZygoteSocket(String socketName)为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);
            }
        }
    }
  • 接着调用系统方法preLoad()
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");
    }

这其中:
preloadClasses()用于初始化Zygote中需要的class类;
preloadResources()用于初始化系统资源;
preloadOpenGL()用于初始化OpenGL;
preloadSharedLibraries()用于初始化系统libraries;
preloadTextResources()用于初始化文字资源;
prepareWebViewInZygote()用于初始化webview;

  • 然后调用startSystemServer(abiList, 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;
    }

可以看到这段逻辑的执行逻辑就是通过Zygote fork出SystemServer进程。

总结:
Zygote进程mian方法主要执行逻辑:

  • 初始化DDMS;

  • 注册Zygote进程的socket通讯;

  • 初始化Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;

  • 初始化完成之后fork出SystemServer进程;

  • fork出SystemServer进程之后,关闭socket连接;

猜你喜欢

转载自blog.csdn.net/mhhyoucom/article/details/78782437