Android SystemServer啓動過程

SystemServer進程主要用於創建系統服務,我們熟知的AMS、WMS和PMS都是由它創建的。

SystemServer由Zygote進程啓動,具體在ZygoteInit.java的forkSystemServer方法中fork了SystemServer進程。

 private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        //...
		//當前運行在SystemServer進程中
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
			//關閉Zygote進程創建的Socket
			//SystemServer進程複製了Zygote進程的地址空間,因此也會得到Zygote進程創建的Socket。
			//這個Socket對於SystemServer進程沒有用處,所以關閉了Socket
            zygoteServer.closeServerSocket();
            //啓動SystemServer進程
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

可以看到這裏調用了handleSystemServerProcess,我們再來看handleSystemServerProcess()

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
   //...
   
   if (parsedArgs.invokeWith != null) {
       //...
   } else {
       ClassLoader cl = null;
       if (systemServerClasspath != null) {
       	   //創建PathClassLoader
           cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

           Thread.currentThread().setContextClassLoader(cl);
       }
	   //調用ZygoteInit.zygoteInit()方法
       return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
   }
}

創建了PathClassLoader字後,又調用了ZygoteInit.zygoteInit,再來看下ZygoteInit#zygoteInit()

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
 	if (RuntimeInit.DEBUG) {
    	Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();

    RuntimeInit.commonInit();
    //啓動Binder線程池
    ZygoteInit.nativeZygoteInit();
    //進入SystemServer的main方法
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

這裏調用了 ZygoteInit.nativeZygoteInit()RuntimeInit.applicationInit(),我們分別來看下

啓動Binder線程池

ZygoteInit.nativeZygoteInit()是一個Native方法,我們先來看下它對應的JNI文件

extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);  
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit(); //gCurRuntime是AndroidRuntime類型的指針,具體指向其子類AppRuntime
}

在來看下AppRuntime的onZygoteInit方法
frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool(); //啓動一個Binder線程池
}

這裏會啓動一個Binder線程池,這樣SystemServer進程就可以使用Binder與其他進程進行通訊了。
看到這裏,我們知道RuntimeInit.java的nativeZygoteInit函數主要是用來啓動Binder線程池的。

進入SystemServer的main方法

我們再回到RuntimeInit.java的代碼,看下RuntimeInit.applicationInit()的內部
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
    //...
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
	Class<?> cl;
	
	try {
		//通過反射得到SystemServer類
	    cl = Class.forName(className, true, classLoader);
	} catch (ClassNotFoundException ex) {
	    throw new RuntimeException(
	            "Missing class when invoking static main " + className,
	            ex);
	}
	
	Method m;
	try {
		//找到SystemServer的main方法
	    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);
	}
	
	//...
	//將找到的main方法傳入MethodAndArgsCaller並返回,最終會拋出該異常
	//這種拋出異常的處理會清除所有的設置過程需要的堆棧幀,並讓SystemServer的main方法看起來像是SystemServer進程的入口方法
	return new MethodAndArgsCaller(m, argv);
}
	
static class MethodAndArgsCaller 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就是SystemServer的main方法,調用mMethod的invoke()之後,
        	//SystemServer的main方法就會被動態調用,SystemServer進程就進入SystemServer的main方法中
            mMethod.invoke(null, new Object[] { mArgs });
        } 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);
        }
    }
}

再來看下在ZygoteInit.java的main方法中時如何捕獲MethodAndArgsCaller異常的

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();
	//...
    final Runnable caller;
    try {
    	//...
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        zygoteServer.closeServerSocket();
    }

    if (caller != null) {
    	//當caller不爲null,則調用caller的run方法,caller是MethodAndArgsCaller
        caller.run();
    }
}

解析SystemServer進程

接着,我們就可以來看SystemServer的main方法了

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

private void run() {
    try {
        //...
        //創建消息Looper
        Looper.prepareMainLooper();
        //...
        //加載了動態庫libandroid_servers.so
        System.loadLibrary("android_servers");
        performPendingShutdown();
		//創建系統的Context
        createSystemContext();
        //創建SystemServerManager,它會對系統服務進行創建、啓動和生命週期管理
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        //啓動引導服務
        //SystermServiceManager啓動了ActivityManagerService、PowerManagerService、PackageManagerService等服務
        startBootstrapServices();
        //啓動核心服務
        //啓動了DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService
        startCoreServices();
        //啓動其他服務
        //啓動了CameraService、AlarmManagerService、VrManagerService等服務
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    //...

    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

可以看到,SystemServer.run中,啓動了各種服務,這些服務都是SystemService的子類。
官方把系統服務分爲了三種類型,分別是引導服務、核心服務和其他服務。
其他服務是一些非緊要和不需要立即啓動的服務,這些服務一共有100多個。

這些系統服務啓動的邏輯是相似的,這裏以啓動PowerManagerService來進行舉例。

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

來看mSystemServiceManager.startService,frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public void startService(@NonNull final SystemService service) {
    //註冊Service,將Service添加到mServices中
    mServices.add(service);
    long time = SystemClock.elapsedRealtime();
    try {
    	//啓動Service,調用service的onStart方法
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}

這樣就完成了PowerManagerService的啓動。

除了通過mSystemServiceManager.startService()的方式來啓動系統服務外,也可以通過比如PackageManagerService.main的方式來啓動系統服務,內部是通過調用SystemManager來註冊。
SystemManager用來管理系統中的各種Service,用於系統C/S架構中的Binder通訊機制 : Client端要使用某個Service,則需要先到ServiceManager查詢Service的相關新,然後根據Service的相關信息與Service所在的Server進程建立通信,這樣Client端就可以使用Service了。

SystemServer小結

SystemServer進程被創建後,主要做了如下的工作

  1. 啓動Binder線程池,這樣就可以與其他進程進行通訊
  2. 創建SystemServiceManager,其用於對系統的服務進行創建、啓動和生命週期管理
  3. 啓動各種系統服務
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章