Android 源码分析(五) Zygote 进程

一.前言:

nit进程 –> Zygote进程 –> SystemServer进程 –> Launcher桌面程序 -> 我们的App应用

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

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

SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
    
    Launcher桌面程序:就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序.

二. Zygote进程

Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的.
       init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法.

  

//ZygoteInit.java
    public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();

        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        try {
            // Report Zygote start time to tron unless it is a runtime restart
            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                MetricsLogger.histogram(null, "boot_zygote_init",
                        (int) SystemClock.elapsedRealtime());
            }

            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            RuntimeInit.enableDdms();
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = 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.");
            }

            zygoteServer.registerServerSocket(socketName);
            // In some configurations, we avoid preloading resources and classes eagerly.
            // In such cases, we will preload things prior to our first fork.
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }

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

            // Do an initial gc to clean up after startup
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();
            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

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

            // Zygote process unmounts root storage spaces.
            Zygote.nativeUnmountStorageOnInit();

            // Set seccomp policy
            Seccomp.setPolicy();

            ZygoteHooks.stopZygoteNoThreadCreation();

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

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

            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }
    //1.registerServerSocket
    //2.调用preload加载资源,
    //3.利用gcAndFinalize初始化gc,
    //4.启动SystemServer,startSystemServer() 这里启动SystemServer服务.
    //5.调用runSelectLoop运行Zygote进程选择的looper,
    //6.关闭和清理zygote sockets
    
//ZygoteServer.java
    /**
     * Registers a server socket for zygote command connections
     *
     * @throws RuntimeException when open fails
     */
    void registerServerSocket(String socketName) {
        if (mServerSocket == 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);
                mServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket ‘" + fileDesc + "‘", ex);
            }
        }
    }
//ZygoteInit.java
    static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
        Log.d(TAG, "begin preload");
        bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
        beginIcuCachePinning();
        bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
        bootTimingsTraceLog.traceBegin("PreloadClasses");
        //初始化Zygote中需要的class类
        preloadClasses();
        bootTimingsTraceLog.traceEnd(); // PreloadClasses
        bootTimingsTraceLog.traceBegin("PreloadResources");
        //初始化系统资源
        preloadResources();
        bootTimingsTraceLog.traceEnd(); // PreloadResources
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
        //初始化OpenGL
        preloadOpenGL();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        //初始化系统libraries
        preloadSharedLibraries();
        //初始化文字资源
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        //初始化webview
        WebViewFactory.prepareWebViewInZygote();
        endIcuCachePinning();
        warmUpJcaProviders();
        Log.d(TAG, "end preload");

        sPreloadComplete = true;
    }
//进去看看初始化webview方法
    //WebViewFactory.java
    /**
     * Perform any WebView loading preparations that must happen in the zygote.
     * Currently, this means allocating address space to load the real JNI library later.
     */
    public static void prepareWebViewInZygote() {
        try {
            System.loadLibrary("webviewchromium_loader");
            long addressSpaceToReserve =
                    SystemProperties.getLong(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY,
                    CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES);
            sAddressSpaceReserved = nativeReserveAddressSpace(addressSpaceToReserve);

            if (sAddressSpaceReserved) {
                if (DEBUG) {
                    Log.v(LOGTAG, "address space reserved: " + addressSpaceToReserve + " bytes");
                }
            } else {
                Log.e(LOGTAG, "reserving " + addressSpaceToReserve +
                        " bytes of address space failed");
            }
        } catch (Throwable t) {
            // Log and discard errors at this stage as we must not crash the zygote.
            Log.e(LOGTAG, "error preparing native loader", t);
        }
    }

原文地址:https://www.cnblogs.com/bugzone/p/zygote.html

时间: 2024-08-29 14:38:28

Android 源码分析(五) Zygote 进程的相关文章

Android源码分析--system_server进程分析

在上一篇博文中我们进行了有关Zygote进程的分析,我们知道Zygote进程创建了一个重要的进程–system_server进程后就进入了无限循环中,之后Android系统中的重要任务就交给了system_server进程,作为zygote的嫡长子进程,system_server进程的意义非凡,今天我们来分析一下system_server进程. 创建system_server进程 在ZygoteInit中main方法中,通过调用startSystemServer方法开启了system_serve

Android源码分析:Telephony部分–phone进程

Android源码分析:Telephony部分–phone进程红狼博客 com.android.phone进程 它就象个后台进程一样,开机即运行并一直存在.它的代码位于:packages/apps/Phone/src/com/android/phone 当有来电时,它会作出反应,如显示UI和铃声提示:当在通话过程中,它显示InCallScreen: 当要拨号时ITeleohony的接口调用最终到Phone进程,然后由它去与PhoneFactory创建的GSMPhone或CDMAPhone进行交互

[Android] Volley源码分析(五)答疑

Volley源码分析系列出了有一段日子了,有不少看官私底下给我留言,同时抛出了一些问题.对于一些比较简单的问题我们跳过去,这两天接到网友是@smali提出的问题.不得不赞一下这位看官看源码时候的细腻程度,我引出这个问题供大家一块思考一下. Q:在写入文件头数据的时候为何不直接写入Int而是通过移位的方式来完成? 我们来看一下对应的源码: writeInt(os, CACHE_MAGIC); static void writeInt(OutputStream os, int n) throws I

Android源码分析:Telephony部分–GSMPhone

Android源码分析:Telephony部分–GSMPhone红狼博客 PhoneProxy/GSMPhone/CDMAPhone 如果说RILJ提供了工具或管道,那么Phone接口的子类及PhoneFactory则为packages/app/Phone这个应用程序进程使用RILJ这个工具或管道提供了极大的方便,它们一个管理整个整个手机的Telephony功能. GSMPhone和CDMAPhone实现了Phone中定义的接口.接口类Phone定义了一套API,这套API用于使用RILJ(见后

Android源码分析之SharedPreferences

在Android的日常开发中,相信大家都用过SharedPreferences来保存用户的某些settings值.Shared Preferences 以键值对的形式存储私有的原生类型数据,这里的私有的是指只对你自己的app可见的,也就是说别的app是无法访问到的. 客户端代码为了使用它有2种方式,一种是通过Context#getSharedPreferences(String prefName, int mode)方法, 另一种是Activity自己的getPreferences(int mo

Android源码分析--MediaServer源码分析(二)

在上一篇博客中Android源码分析–MediaServer源码分析(一),我们知道了ProcessState和defaultServiceManager,在分析源码的过程中,我们被Android的Binder通信机制中的各种复杂的类关系搞的眼花缭乱,接下来我们就以MediaPlayerService为例来分析一下Binder的通信机制.首先来回顾一下: BpBinder和BBinder都是Android中Binder通信的代表类,其中BpBinder是客户端用来与Server交互的代理类,p代

Android源码分析(十七)----init.rc文件添加脚本代码

一:init.rc文件修改 开机后运行一次: chmod 777 /system/bin/bt_config.sh service bt_config /system/bin/bt_config.sh class main user root group root oneshot 开机后等待android启动完成后再运行: service bt_config /system/bin/bt_config.sh class main user root group root disabled one

Cordova Android源码分析系列一(项目总览和CordovaActivity分析)

PhoneGap/Cordova是一个专业的移动应用开发框架,是一个全面的WEB APP开发的框架,提供了以WEB形式来访问终端设备的API的功能.这对于采用WEB APP进行开发者来说是个福音,这可以避免了原生开发的某些功能.Cordova 只是个原生外壳,app的内核是一个完整的webapp,需要调用的原生功能将以原生插件的形式实现,以暴露js接口的方式调用. Cordova Android项目是Cordova Android原生部分的Java代码实现,提供了Android原生代码和上层We

Android 源码分析工具

标 题: [原创]Android源码分析工具及方法作 者: MindMac时 间: 2014-01-02,09:32:35链 接: http://bbs.pediy.com/showthread.php?t=183278 在对 Android 源码进行分析时,如果有得力的工具辅助,会达到事半功倍的效果.本文介绍了一些在分析 Android 源码时使用的一些工具和方法,希望能够帮助到有需要的同学. Eclipse 在 Android 应用程序开发过程中,一般会使用 Eclipse,当然 Googl

Android源码分析之SparseArray

本来接下来应该分析MessageQueue了,可是我这几天正好在实际开发中又再次用到了SparseArray(之前有用到过一次,那次只是 大概浏览了下源码,没做深入研究),于是在兴趣的推动下,花了些时间深入研究了下,趁着记忆还是新鲜的,就先在这里分析了. MessageQueue的分析应该会在本周末给出. 和以往一样,首先我们来看看关键字段和ctor: private static final Object DELETED = new Object(); private boolean mGar