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系統服務:
系統服務有很多,這裡隻展示一部分,以後再篩選用的比較多的來進行分析。我們接着剛剛的啟動服務代碼看:
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;
-
- 啟動Binder線程池,這樣就可以與其他程序進行通信;
- 3.建立SystemServiceManager用于對系統的服務進行建立、啟動和生命周期管理;
- 4.SystemServer程序主要用于啟動系統中的服務并進行管理。
- 5.服務對象都有自己的異步消息對象,并運作在單獨的線程中;