天天看點

Android源碼解析--SystemServer啟動流程

1.前言

在整個android系統中,程序的啟動流程如下:

  • init程序 –> Zygote程序 –> SystemServer程序 –>各種應用程序

先啟動init程序,它是整個linux系統的根程序,接着啟動了Zygote程序,它是Android系統的根程序,接着啟動的就是本文要講到的SystemServer程序,它管理着Android系統的各種系統服務,然後才是啟動各種上層應用程序。

SystemServer也是Android Java的兩大支柱,另一大支柱是專門負責孵化Java程序的Zygote程序(SystemServer也是由其孵化),這兩大支柱任何一個倒了都會導緻Android Java崩潰,然後Linux系統的init程序 會重新啟動兩大支柱 以重建 Android Java。

2. Zygote程序啟動SyetemServer程序

剛剛提到,System_server是在Zygote程序中被啟動的,源碼在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 中:

public static void main(String argv[]) {
 ...
  if (startSystemServer) {
     startSystemServer(abiList, socketName);
  }
 ...
}


/**
 * 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 */
    String args[] = { // 注釋1 啟動System_server的相關固定參數
        "--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(//注釋2 從Zygote fork System_server程序
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } 
	...
    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
		//注釋3 完成剛啟動的System_server程序的剩餘部分工作
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}
           

相關的代碼解釋已經寫在注釋中了,上面注釋3 調用的方法是用來做啟動System_server程序後一些剩餘的工作,看代碼:

/**
 * Finish remaining work for the newly forked system server process.
 */
private static void handleSystemServerProcess(
        ZygoteConnection.Arguments parsedArgs)
        throws ZygoteInit.MethodAndArgsCaller {main

    closeServerSocket();//注釋1 關掉socket, Android中除了Zygote程序,其他程序之間的通信都是通過Binder完成
 ...
        /*
         * Pass the remaining arguments to SystemServer.
         */
		//注釋2 調用此方法會啟動Binder線程池 以及 啟動SystemServer
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
  ...
}
           

上述代碼中,注釋1 SyetemServer程序是複制了Zygote程序的位址空間,是以也會得到Zygote程序建立的Socket,這個Socket對于SyetemServer程序沒有用處,是以關閉。 注釋2中,調用RuntimeInit的zygoteInit函數會啟動System_server的Binder線程池,跟進代碼RuntimeInit.zygoteInit:

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
   	...
    nativeZygoteInit();//注釋1
    applicationInit(targetSdkVersion, argv, classLoader);//注釋2
}
           

此處 注釋1 去啟動了Binder線程池, 注釋2進入了 System_server的 main方法,注釋1最終會進入native層,感興趣的可以跟進去,我們接着看注釋2:

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
   ...
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
           

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) {
        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);
    }

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

此處通過反射調用了SystemServer的main方法,并以抛出MethodAndArgsCaller這個 異常方式讓其被 ZygoteInit.java的main函數捕獲:

public static void main(String argv[]) {
   ...
        closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
        caller.run();//注釋1
    } catch (RuntimeException ex) {
        Log.e(TAG, "Zygote died with exception", ex);
        closeServerSocket();
        throw ex;
    }
}
           

在注釋1 調用了 run方法,進入這個run方法:

public static class MethodAndArgsCaller extends Exception
        implements Runnable {
	...
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try { //此處反射區調用 SystemServer的 main方法
            mMethod.invoke(null, new Object[] { mArgs });
        } 
	...
    }
}
           

3. 進入SystemServer程序

首先進入SystemServer程序的main函數:

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

,進入了run :

private void run() {
    try {
        //初始化時間,最早隻能是1970年
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
 		...
        // Mmmmmm... more memory!
        VMRuntime.getRuntime().clearGrowthLimit();

        //由于SystemServer程序一直在運作,是以記憶體使用率要盡可能高一些
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        // 有些裝置依賴于運作時指紋生成,是以請確定在進一步啟動之前已經定義了指紋。
        Build.ensureFingerprintProperty();

        // 調用目前程序的mainLooper的 prepare
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

        // SystemServer的 JNI代碼
        System.loadLibrary("android_servers");
		...
        // 【注釋1】初始化目前程序的 Context
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    try {
        startBootstrapServices();//【注釋2】 啟動引導服務
        startCoreServices();//【注釋3】  啟動核心服務
        startOtherServices();//【注釋4】  啟動其他服務
    }
	...
    // 開啟消息死循環 
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
           

run方法内容很多,我們把關鍵的找出來,上面注釋1 初始了目前程序的上下文Context:

private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
           

在SystemServer中,其他應用的Activity等Context都是以 ActivityThread的形式存在。

注釋2、3、4就是啟動SystemServer管理的各種Android系統服務:

Android源碼解析--SystemServer啟動流程

系統服務有很多,這裡隻展示一部分,以後再篩選用的比較多的來進行分析。我們接着剛剛的啟動服務代碼看:

private void startBootstrapServices() {
    //需要在安裝應用前啟動此服務,才能建立關鍵目錄,如具有适當權限的/data/user。我們需要在初始化其他服務之前完成此操作。
    Installer installer = mSystemServiceManager.startService(Installer.class);

    //啟動 Activity manager 
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

	mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
...
}
           

在代碼中看到,在上述注釋【3】【4】【5】啟動的各種服務,通常都是通過 mSystemServiceManager.startService()來啟動的,然後會調用add(service) :

/**
 * Starts a service by class name.
 * @return The service instance.
 */
public SystemService startService(String className) {
    final Class<SystemService> serviceClass;//此處泛型為SystemService,說明所有的服務類都必須實作SystemService
    try {
        serviceClass = (Class<SystemService>)Class.forName(className);
    } catch (ClassNotFoundException ex) {
        Slog.i(TAG, "Starting " + className);
        throw new RuntimeException("Failed to create service " + className
                + ": service class not found, usually indicates that the caller should "
                + "have called PackageManager.hasSystemFeature() to check whether the "
                + "feature is available on this device before trying to start the "
                + "services that implement it", ex);
    }
    return startService(serviceClass); // 注釋1
}
           

此處注釋1 繼續往下跟:

/**
 * 建立一個系統服務,該服務必須實作SystemService接口
 *
 * @return 傳回執行個體或者 null
 * @throws RuntimeException if the service fails to start.
 */
public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();

        // Create the service.
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service could not be instantiated", ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service constructor threw an exception", ex);
        }

        // Register it.
        mServices.add(service);//【注釋1】 添加服務,注冊到SystemServer

        // Start it.
        try {
            service.onStart();//【注釋2】 啟動服務
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + name
                    + ": onStart threw an exception", ex);
        }
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}
           

建立服務成功後,在注釋1 處 将服務注冊到SystemServer, 注釋2 啟動服務

4、 總結

SyetemServer啟動流程梳理:

  • 1.Zygote程序fork出SystemServer程序,并關閉沒用的socket;
    1. 啟動Binder線程池,這樣就可以與其他程序進行通信;
  • 3.建立SystemServiceManager用于對系統的服務進行建立、啟動和生命周期管理;
  • 4.SystemServer程序主要用于啟動系統中的服務并進行管理。
  • 5.服務對象都有自己的異步消息對象,并運作在單獨的線程中;