1. 程式人生 > >Android 7.0系統啟動流程分析

Android 7.0系統啟動流程分析

隨著Android版本的升級,aosp專案中的程式碼也有了些變化,本文基於Android 7.0分析Android系統啟動流程.當我們按下電源鍵後,整個Android裝置大體經過了一下過程:
這裡寫圖片描述

今天我們只想來分析init程序及其後的過程,也就是下圖所示部分:
這裡寫圖片描述

init程序

init程序會解析init.rc檔案(關於init.rc中的語法,可以參見之前寫的深入分析AIL語言及init.rc檔案),載入相關分割槽,並啟動相關服務.

init程序在/system/core/init/init.cpp
init.rc檔案在/system/core/rootdir下
init.rc檔案由parser.cpp解析,在/system/core/init/init_parser.cpp

在init.rc中,Zygote程序被啟動.Zygote程序是其他所有程序的孵化器.init.rc通過include引入init.zygote.rc,這裡以init.zygote64.rc為例:

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc
    socket zygote stream 660 root system
    onrestart write
/sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd writepid /dev/cpuset/foreground/tasks

對個指令碼簡單分析:

  1. service zygote /system/bin/app_process64 :service命令告訴init程序要建立一個名字為zygote的程序,這個zygote程序執行的程式是/system/bin/app_process64,後面是傳給app_process64程式的引數.
  2. socket zygote stream 660 root system:表示zygote程序需要一個名為”zygote”的socket,該socket用來實現程序間的通訊.當新啟動一個應用時,ActivityManagerService想向該Socket發起請求,請求zygote程序fork出一個新的程序.
  3. 後面的onrestart表示zygote重啟時需要執行的動作.

Zygote程序啟動

上面說到init程序會根據init.rc執行相關的操作,其中有一項就是建立Zygote程序.Zygote程序所對應的程式是/system/bin/app_process,
位於/frameworks/base/cmds/app_process/app_main.cpp,其入口函式是main():

int main(int argc, char* const argv[])
{
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
        LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
    }

    if (!LOG_NDEBUG) {
      String8 argv_String;
      for (int i = 0; i < argc; ++i) {
        argv_String.append("\"");
        argv_String.append(argv[i]);
        argv_String.append("\" ");
      }
      ALOGV("app_process main with argv: %s", argv_String.string());
    }

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;
    const char* spaced_commands[] = { "-cp", "-classpath" };

    bool known_command = false;

    int i;
    for (i = 0; i < argc; i++) {
        if (known_command == true) {
          runtime.addOption(strdup(argv[i]));
          ALOGV("app_process main add known option '%s'", argv[i]);
          known_command = false;
          continue;
        }

        for (int j = 0;
             j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
             ++j) {
          if (strcmp(argv[i], spaced_commands[j]) == 0) {
            known_command = true;
            ALOGV("app_process main found known command '%s'", argv[i]);
          }
        }

        if (argv[i][0] != '-') {
            break;
        }
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            ++i; // Skip --.
            break;
        }

        runtime.addOption(strdup(argv[i]));
        ALOGV("app_process main add option '%s'", argv[i]);
    }

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //init.zygote64.rc中接受的引數,表示啟動SystemServer元件
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    Vector<String8> args;
    if (!className.isEmpty()) {

        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);

        if (!LOG_NDEBUG) {
          String8 restOfArgs;
          char* const* argv_new = argv + i;
          int argc_new = argc - i;
          for (int k = 0; k < argc_new; ++k) {
            restOfArgs.append("\"");
            restOfArgs.append(argv_new[k]);
            restOfArgs.append("\" ");
          }
          ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
        }
    } else {
        // We're in zygote mode.
        maybeCreateDalvikCache();

        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }

        char prop[PROP_VALUE_MAX];
        if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
            LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                ABI_LIST_PROPERTY);
            return 11;
        }

        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }

    if (zygote) {
        //此處見到了我們熟悉的ZygoteInit,但該方法的具體實現在//AndroidRuntime.start()
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

上述程式碼總體比較簡單,主要是處理相關引數,並建立AppRuntime,由於在init.rc檔案中,app_process啟動引數被設定為--zygote --start-system-server,因此會執行runtime.start("com.android.internal.os.ZygoteInit", args, zygote),現在我們來看看AppRuntime的具體實現,它同樣在
在/frameworks/base/cmds/app_process/app_main.cpp:

class AppRuntime : public AndroidRuntime
{
public:
    AppRuntime(char* argBlockStart, const size_t argBlockLength)
        : AndroidRuntime(argBlockStart, argBlockLength)
        , mClass(NULL)
    {
    }

    void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
        mClassName = className;
        for (int i = 0; i < argc; ++i) {
             mArgs.add(String8(argv[i]));
        }
    }

    virtual void onVmCreated(JNIEnv* env)
    {
        if (mClassName.isEmpty()) {
            return; // Zygote. Nothing to do here.
        }

        char* slashClassName = toSlashClassName(mClassName.string());
        mClass = env->FindClass(slashClassName);
        if (mClass == NULL) {
            ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
        }
        free(slashClassName);

        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
    }

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

        AndroidRuntime* ar = AndroidRuntime::getRuntime();
        ar->callMain(mClassName, mClass, mArgs);

        IPCThreadState::self()->stopProcess();
    }

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

    virtual void onExit(int code)
    {
        if (mClassName.isEmpty()) {
            // if zygote
            IPCThreadState::self()->stopProcess();
        }

        AndroidRuntime::onExit(code);
    }


    String8 mClassName;
    Vector<String8> mArgs;
    jclass mClass;
};

AppRuntime繼承AndroidRuntime,而AndroidRuntime位於
/frameworks/base/core/jni/AndroidRuntime.cpp.
而start()方法便是定義在AndroidRuntime的虛方法:

//這裡的className的值就是com.android.intrnal.os.ZygoteInit
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   //...省略多行程式碼

    static const String8 startSystemServer("start-system-server");

    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //1. 啟動虛擬機器
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    //2. 呼叫startReg()註冊JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }

    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
         //3. 本質就是呼叫com.android.intrnal.os.ZygoteInit類的main函式
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);

   // 省略多行程式碼
}

在start()方法中主要做三件事情:
1. 呼叫startVM()函式啟動虛擬機器
2. 呼叫startReg()註冊JNI方法
3. 呼叫com.android.internal.os.ZygoteInit.java類的main函式.

走進ZygoteInit

關於前兩者就不細說了,重點來關注我們熟悉的ZygoteInit.java.它在
rameworks/base/core/Java/com/android/internal/os/ZygoteInit.java,我們直接來看他的main方法:

public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();
        ZygoteHooks.startZygoteNoThreadCreation();
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        try {
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
            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.");
            }
            //建立名為zygote的socket
            zygoteServer.registerServerSocket(socketName);
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
           //省略多行引數
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
            gcAndFinalize();
            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
            Trace.setTracingEnabled(false);
            Zygote.nativeUnmountStorageOnInit();

            ZygoteHooks.stopZygoteNoThreadCreation();
            //由於在init.rc中設定了start-system-server引數,因此
            //這裡將啟動SystemServer,可見SystemServer由Zygote創        //建的第一個程序
            if (startSystemServer) {
                //啟動SystemServer元件
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            //等待ActivityManagerService請求
            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;
        }
    }

這裡的main()方法中主要做了三件事情
1. 通過registerServerSocket()來建立Socket,它將作為服務端用來和作為客戶端的ActivityManagerService進行通訊
2. 通過startSystemServer()方法來啟動SystemServer
3. 最後通過通過runSelectLoop方法使得剛才建立的Socket進入無限迴圈,以等待來自ActivityManagerService請求

Zygote中Socket建立

首先來看resiterServerSocket()它在:

  void registerServerSocket(String socketName) {
        if (mServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                //從環境變數env中獲取檔案描述符,
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                //通過檔案描述符建立socket,該描述符代表/dev/socket/zygote檔案.
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                mServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

方法主要通過檔案描述符建立socket,該檔案描述代表/dev/socket/zygote檔案,現在看看開頭init.rc中的配置:socket zygote stream 660 root system

Zygote啟動SystemServer

現在來看startSystemServer()方法:

    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_IPC_LOCK,
            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,
            OsConstants.CAP_WAKE_ALARM
        );

        if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
            capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
        }
        /* 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,3009,3010",
            "--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);

            //建立子程序
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        //pid=0表示子程序,此處就是SystemServer程序
        if (pid == 0) {
            //用於處理系統中有兩個Zygote程序的情況,由於通常我們不會配置兩個Zygote,因此暫時不關注
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            //Zygote建立的子程序(此處就是SystemServer)不需要使用Zygote中建立的Socket檔案描述符,因此通過closeServerSocket()關閉它.
            zygoteServer.closeServerSocket();
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

這裡首先通過Zygote.forkSystemServer()建立一個系統服務程序.與該方法相似還有forkAndSpecialize(),用於建立一個普通應用程序.程序建立成功後返回pid為0.由於此處生成的新程序和Zygote程序一模一樣,也就是說這個新程序中同樣包含了剛才建立的Socket,但是該Socket在此處無效,因此要將其關閉.接下來呼叫handleSystemServerProcess()處理剛才新建的程序即SystemServer程序,需要注意此時已經工作在SystemServer程序中了:

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
        //省略多行程式碼,此處invokeWith為null
        if (parsedArgs.invokeWith != null) {
            String[] args = parsedArgs.remainingArgs;

            if (systemServerClasspath != null) {
                 //省略多行程式碼  
             } else {

            ClassLoader cl = null;
            if (systemServerClasspath != null) {
            //為SysteServer程序建立PathClassLoader類載入器
                cl = createSystemServerClassLoader(systemServerClasspath,
                                            parsedArgs.targetSdkVersion);

Thread.currentThread().setContextClassLoader(cl);
            }

            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

    }

該函式繼續呼叫RuntimeInit.zygoteInit()進一步執行啟動SystemServer元件的操作.繼續來看 RuntimeInit.zygoteInit()的具體實現,它在
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java檔案中:

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        //...省略多行程式碼

        commonInit();
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }

在該方法中主要呼叫了三個方法:

  • commonInit():為當前程序的VM設定未捕獲異常處理器
  • nativeZygoteInit():Binder驅動初始化,該方法完成後,就可以通過該Binder進行程序通訊
  • applicationInit():主要用呼叫com.android.server.SystemServer類的main()方法

由於commonInit()方法比較簡單,在此就不做分析.
nativeZygoteInit()是一個本地方法,其對應實現在frameworks/base/core/jni/AndroidRuntime.cpp中:

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

這裡的gCurRuntime是AppRuntime的指標,在frameworks/base/core/jni/AndroidRuntime.cpp中定義,並在AndroidRuntime的夠贊函式中初始化:

//定義
static AndroidRuntime* gCurRuntime = NULL;

...

//在frameworks/base/cmds/app_process/app_main.cpp的main()方法中被呼叫
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
        mExitWithoutCleanup(false),
        mArgBlockStart(argBlockStart),
        mArgBlockLength(argBlockLength)
{
    SkGraphics::Init();
    mOptions.setCapacity(20);

    assert(gCurRuntime == NULL);
    gCurRuntime = this;
}

繼續來看onZygoteInit():

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

這裡呼叫ProcessState::startThreadPool()方法啟動執行緒池,這個執行緒池就是用來和Binder驅動程式程序互動的.(Binder驅動本質就是一個檔案,位於/dev/binder),關於執行緒池具體建立的過程暫不做說明.

現在來看applicationInit():

    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
         //省略多行程式碼
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

這裡繼續呼叫了invokeStaticMain()進行後續工作:

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

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

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            //...
        } catch (SecurityException ex) {
            //...
        }

       // 省略多行程式碼

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

此時要執行的是com.android.server.SystemServer的中mian()方法.此外真正執行的過程是在Zygote.MethodAndArgsCaller的run()方法中:

    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 });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
               //省略多行程式碼
            }
        }
    }

MethodAndArgsCaller繼承Exception並實現Runnable介面,作為一個異常他被ZygoteInit.main()捕獲並處理:

   public static void main(String argv[]) {
        // ...
        try {
             //...省略多行程式碼
             startSystemServer(abiList, socketName);
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            //...
        }
    }

現在SystemServer的main()已經被呼叫,我們順著來看一下實現:

public class SystemServer{

  public static void main(String[] args) {
        new SystemServer().run();
    }


    private void run() {
        try {
            //...省略一些初始化操作

            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            //初始化主執行緒Looper
            Looper.prepareMainLooper();

            //建立SystemServiceManager物件
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

            // 啟動關鍵服務
            startBootstrapServices();
            //啟動核心服務
            startCoreServices();
            //啟動其他服務
            startOtherServices();
            //...省略多行程式碼

            //啟動訊息迴圈
            Looper.loop();

    }

}

在main()方法中呼叫了run()方法繼續啟動操作.在run方法中這三個方法非常重要:

  1. startBootstrapServices():啟動引導服務,比如AMS,PMS等
  2. startCoreServices():啟動核心服務,比如BatteryService等
  3. startOtherServices():啟動其他服務,比如NetworkStatsService等.

關於SystemService的具體執行過程,在此不做細解.

Socket迴圈監聽

到目前為止,關於ZygoteServer.registerServerSocket()startSystemServer()的大體流程我們已經弄清除,接下來就是ZygoteServer.runSelectLoop()方法:

void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(mServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                   //監聽Socket連結,如果你做過Socket程式設計就發現此處充當了服務端Socket
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    //重點關注runOnce()方法
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

該方法非常簡單:不斷的處理來自客戶端AMS的請求,然後交給runOnce().此處可見Android 7.0應用啟動流程分析

到現在為止,整個SystemServer程序的啟動流程已經明確看,用一張順序圖大體的表示上述的整個流程:
這裡寫圖片描述

總結

  1. 系統啟動時init程序會建立Zygote程序,Zygote程序負責後續Android應用框架層的其他程序的建立和啟動.
  2. Zygote程序會首先建立一個SystemSever程序,然後由SystemServer負責啟動系統關鍵服務,如ActivityManagerService或者PackageManagerService等.