Android系統(tǒng)啟動(dòng)系列----Zygote進(jìn)程

引言

上一篇文章Android系統(tǒng)啟動(dòng)系列----init進(jìn)程,大體分析了,init進(jìn)程的啟動(dòng)過程。同時(shí)最后講到了Zygote進(jìn)程是由app_process進(jìn)程通過JNI調(diào)用了ZygoteInit的main方法啟動(dòng)的。這一篇文章將分析Zygote進(jìn)程都為我們做了什么。(系統(tǒng)源碼分析基于Android 6.0.1)


Zygote功能

首先來看看ZygoteInit的main方法都做了啥:(/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)

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);       //  1
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();          //  2
            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);   //  3
            }

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

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();   //  5
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }
  1. 注釋1:注冊(cè)socket通信的服務(wù)端
  2. 注釋2:預(yù)加載
  3. 注釋3:?jiǎn)?dòng)SystemServer系統(tǒng)服務(wù)
  4. 注釋4:循環(huán)等待socket客戶端的連接請(qǐng)求(如啟動(dòng)新的應(yīng)用app等)
  5. 注釋5:執(zhí)行運(yùn)行socket客戶端的請(qǐng)求者的main方法

注冊(cè)socket通信的服務(wù)端(registerZygoteSocket)

注冊(cè)一個(gè)名字為“zygote”的socketserver:

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);  // 1
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

注釋1:創(chuàng)建一個(gè)serversocket靜態(tài)對(duì)象

預(yù)加載(preload)

static void preload() {
        Log.d(TAG, "begin preload");
        preloadClasses();               // 預(yù)加載一些字節(jié)碼class文件類
        preloadResources();           //  預(yù)加載一些資源
        preloadOpenGL();                //  預(yù)加載OpenGL相關(guān)顯示信息
        preloadSharedLibraries();    //  預(yù)加載動(dòng)態(tài)共享so庫:如android、jnigraphics等so庫
        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");
    }

啟動(dòng)SystemServer系統(tǒng)服務(wù)

/**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
            
            .....
            
        /* Hardcoded command line to start the system server */
        //////////////////////  1
        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 */
            //////////////////////  2
            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);
            }
            //////////////////////  3
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

a. 注釋1:設(shè)置啟動(dòng)systemServer的一些參數(shù)
b. 注釋2:根據(jù)參數(shù)fork一個(gè)叫system_server的進(jìn)程

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        VM_HOOKS.preFork();
        int pid = nativeForkSystemServer(
                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
        // Enable tracing as soon as we enter the system_server.
        if (pid == 0) {
            Trace.setTracingEnabled(true);
        }
        VM_HOOKS.postForkCommon();
        return pid;
    }

nativeForkSystemServer方法是native本地方法作用就是fork一個(gè)SystemServer進(jìn)程。

c. 注釋3:當(dāng)注釋2的pid = 0,表示if里的語句執(zhí)行在SystemServer進(jìn)程中,啟動(dòng)com.android.server.SystemServer類的main方法。

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        .......

        if (parsedArgs.invokeWith != null) {
            String[] args = parsedArgs.remainingArgs;
            ........

            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.
             */
             //////////////////////////// 1
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

注釋1,將SystemServer的一些參數(shù)傳入RuntimeInit.zygoteInit方法。
再來看看RuntimeInit.zygoteInit方法:

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
            
        ......
        
        nativeZygoteInit();       ///////////////////  1
        applicationInit(targetSdkVersion, argv, classLoader);     /////////////////////////  2
    }
  • 注釋1:native層做了些初始化,來看看,native方法對(duì)應(yīng)在/frameworks/base/core/jni/AndroidRuntime.java中。

    static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        gCurRuntime->onZygoteInit();
    }
    

    onZygoteInit 是一個(gè)虛函數(shù),那它的實(shí)現(xiàn)類是在哪呢,還記得上篇文章app_process進(jìn)程的app_main.cpp文件中有個(gè)AppRuntime類么,runtime.start()啟動(dòng)了Zygote進(jìn)程,AppRutime類繼承了AndroidRuntime,并實(shí)現(xiàn)了onZygoteInit方法。

    virtual void onZygoteInit()
        {
            sp<ProcessState> proc = ProcessState::self();
            ALOGV("App process: starting thread pool.\n");
            proc->startThreadPool();
        }
    

    這里proc啟動(dòng)了一個(gè)線程池,它是binder的線程池,以后會(huì)詳細(xì)分析binder線程池,用于跨進(jìn)程的通信。

  • 注釋2: java層的初始化applicationInit()

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        
        .......
        
        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

繼續(xù)看invokeStaticMain方法:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

        try {
        /////////////////////   1
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
        ///////////////////    2
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        ///////////////////    3
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

我們知道一路下來入?yún)lassName就是com.android.server.SystemServer
注釋1: 通過反射Class.forName加載出com.android.server.SystemServer的SystemServer.class對(duì)象。
注釋2:通過SystemServer.class對(duì)象的獲取SystemServer的main方法的Method對(duì)象。
注釋3:這個(gè)方法完了也沒有實(shí)際的通過反射去invoke SystemServer的main方法,而是拋出了ZygoteInit.MethodAndArgsCaller異常并把main方法的Method對(duì)象和參數(shù)傳入進(jìn)去。很顯然肯定就是這個(gè)異常類處理了。那就要找到哪里try....catch了這個(gè)異常信息并處理。最終可以看到在最初的ZygoteInit.main()方法。

try{
......
} catch (MethodAndArgsCaller caller) {
            caller.run();   //  5
        } 
public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });  ///////////   1
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

注釋1:mMethod對(duì)象就是上文中SystemServer的main方法的Method對(duì)象,通過invoke調(diào)用了main方法。這樣SystemServer就運(yùn)行了main方法。

循環(huán)等待socket客戶端的連接請(qǐng)求(如啟動(dòng)新的應(yīng)用app等)

這里不詳細(xì)介紹了,就是while(true) 不斷的等待有客戶端的請(qǐng)求。

執(zhí)行調(diào)用socket客戶端的請(qǐng)求者傳入的Mehod對(duì)象方法

這里其中的一個(gè)處理在上文MethodAndArgsCaller類中run()方法的處理已經(jīng)分析了。


總結(jié)

  1. 通過app_process進(jìn)程啟動(dòng)ZygoteInit.main()函數(shù)。
  2. 首先注冊(cè)了serverSocket。
  3. fork啟動(dòng)SystemServer進(jìn)程,并通過native方法開啟binder線程池,便于提供給SytemServer進(jìn)行跨進(jìn)程通信。
  4. 等待socket客戶端的連接請(qǐng)求
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容