文章已同步Github博客:SystemServer進程啓動
使用到的相關源碼:https://github.com/JesusYoung/AndroidResourceCode9.0/tree/master
基於Android 9.0
1、SystemServer進程作用
SystemServer進程主要是用於創建系統服務的,例如AMS、WMS、PMS;
SystemService進程被創建後,主要的處理如下:
- 初始化一些系統設置,虛擬機配置等;
- 啓動Binder線程池,這樣就可以與其他進程進行Binder跨進程通信;
- 創建SystemServiceManager,它用來對系統服務進行創建、啓動和生命週期管理;
- 創建主線程Looper並進入循環等待消息;
- 啓動各種系統服務:引導服務、核心服務、其他服務,如引導服務ActivityManagerService、PackageManagerService和其他服務WindowManagerService、InputManagerService即可;
2、SystemServer進程啓動流程
2.1、Zygote進程調用
2.1.1、啓動參數
在Init進程啓動時,解析init.rc文件時,拿到相關啓動參數,其中參數中包含“–start-system-server”,表示啓動時要啓動SystemServer進程,最終Zygote進程拿到相關參數,所以startSystemServer值爲true;
2.1.2、Zygote進程fork
在Zygote進程啓動後,執行ZygoteInit類的main()方法,通過fork的方式啓動SystemServer;
啓動完SystemServer之後會返回一個Runnable對象,在父進程Zygote中該Runnable對象爲null,子進程SystemServer中不爲null,會在SystemServer進程中執行該Runnable對象;
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
boolean startSystemServer = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
}...
}
...
zygoteServer.registerServerSocketFromEnv(socketName);
...
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
...
}
在forkSystemServer()方法中,通過硬編碼的方法寫入啓動參數數組,調用ZygoteConnection.Arguments類去解析該參數數組,最後調用Zygote類的forkSystemServer()方法去請求fork SystemServer進程;
如果fork成功,在父進程中會返回子進程的pid,子進程中會返回pid=0,並且子進程會繼續從該處執行,判斷pid大於0,如果有兩個Zygote進程,則需要等待另一個也完成,然後子進程清除調從父進程fork過來的socket信息,繼續執行handleSystemServerProcess()方法;
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
...
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
...
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
在Zygote的forkSystemServer()方法中,會先重置線程優先級,然後調用native方法去執行fork;
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
...
VM_HOOKS.postForkCommon();
return pid;
}
native private static int nativeForkSystemServer(int uid, int gid, int[] gids,
int runtimeFlags, int[][] rlimits,
long permittedCapabilities,
long effectiveCapabilities);
2.1.3、進入Native層方法
Zygote類對應的native方法在AndroidRuntime.cpp中註冊的,調用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射關係;
在native方法中又調用ForkAndSpecializeCommon()方法,創建完成後Zygote進程會去檢查SystemServer是否已經啓動,如果system_server創建失敗後,會重啓zygote進程,Zygote進程和SystemServer進程是Android系統的兩個重要的進程,二者缺一不可,否則就無法正常運行;
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags,
jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, false, NULL, NULL);
...
if (pid > 0) {
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}
2.1.4、fork進程
在ForkAndSpecializeCommon()方法中,調用fork()函數去從父進程Zygote中fork出子進程,即SystemServer進程,然後根據進程pid去判斷,做一些初始化工作;
在進程fork的時候,操作系統會複製一個與父進程完全相同的子進程,共享代碼空間,但是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也完全相同,子進程擁有父進程當前運行到的位置(兩進程的程序計數器pc值相同,也就是說,子進程是從fork返回處開始執行的),但是兩者返回的pid是不同的,如果fork成功,子進程中會返回pid=0,父進程Zygote中會返回子進程的pid,fork失敗父進程中會返回負數;
子進程SystemServer創建成功之後,會將從父進程拷貝過來的數據做一些初始化操作;
// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint runtime_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jintArray fdsToIgnore, bool is_child_zygote,
jstring instructionSet, jstring dataDir) {
SetSignalHandlers();
...
pid_t pid = fork();
if (pid == 0) {
// pid = 0 爲在子進程中,即SystemServer進程,然後做一系列初始化工作
...
} else if (pid > 0) {
// pid > 0 爲在父進程中,即Zygote進程
...
}
return pid;
}
2.1.5、Java層獲取到結果
此時子進程SystemServer進程fork成功,順着調用的API返回到ZygoteInit類的forkSystemServer()方法中,此時在Native層fork進程完成,結果返回到Java層,SystemServer進程從fork之後開始執行,即handleSystemServerProcess();
2.1.6、SystemServer進程相關設置
初始化SystemServer進程名,創建類加載器等,繼續調用zygoteInit()方法;
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
...
// 設置進程名
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
...
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
在該方法中做一些初始化操作,如日誌定向,通用初始化即Zygote的初始化,最後調用applicationInit()方法;
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
...
// 日誌相關
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
RunTimeInit類中的commonInit()方法主要初始化一些通用配置,如日誌、時區、Http User-agent、socket的tag等;
protected static final void commonInit() {
...
// 設置時區
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);
...
// 設置默認的HTTP User-agent格式
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
...
}
在applicationInit()方法中初始化程序退出時的設置,設置虛擬機內存利用率參數,sdk版本等,隨後繼續調用findStaticMain()方法;
protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
// 程序退出時相關設置
nativeSetExitWithoutCleanup(true);
// 設置虛擬機的內存利用率參數值爲0.75
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
...
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
2.1.7、進入SystemServer進程main方法
在findStaticMain()方法中通過反射找到SystemServer類的main()方法,將其作爲參數新建MethodAndArgsCaller對象,MethodAndArgsCaller是一個Runnable對象,其run方法裏是調用該傳入的方法,即執行SystemServer類的main()方法;
protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) {
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);
}
...
return new MethodAndArgsCaller(m, argv);
}
2.2、SystemServer進程工作
SystemServer的run()方法中,做了大量的初始化操作,如設置系統時間、設置虛擬機相關配置參數、binder調用相關、創建主線程Looper並循環等待消息、並創建SystemServerManager等;
public final class SystemServer {
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
VMRuntime.getRuntime().clearGrowthLimit();
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
Build.ensureFingerprintProperty();
Environment.setUserRequired(true);
BinderInternal.disableBackgroundScheduling(true);
BinderInternal.setMaxThreads(sMaxBinderThreads);
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
...
// Initialize the system context.
createSystemContext();
mSystemServiceManager = new SystemServiceManager(mSystemContext);
} finally {
...
}
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
...
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
此時SystemServer進入自身的Looper循環中,等待消息處理,SystemServer進程正式運行起來了;
2.2.1、初始化配置
SystemServer啓動之後,會執行一系列初始化操作,如判斷系統時間是否早於1970年,設置系統時間、虛擬機內存設置、加載指紋信息、Binder調用的優先級、Binder線程池的最大數量、創建主線程Looper、加載android_servers庫、初始化系統上下文、創建SystemServerManager等;
2.2.2、創建SystemServerManager
在run()方法中,會先執行createSystemContext()方法創建系統上下文對象,mSystemContext對象是從ActivityThread獲取的,調用ActivityThread的systemMain()方法,執行其attach()方法,創建出App的context,及執行Application的onCreate()方法,系統上下文對象是通過ActivityThread的getSystemContext()方法獲取,調用ContextImpl類的createSystemContext()方法創建;
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
# ActivityThread
public static ActivityThread systemMain() {
...
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
private void attach(boolean system, long startSeq) {
...
if (!system) {
...
} else {
...
try {
...
ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException("Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
拿到上下文對象,去創建SystemServerManager對象;
mSystemServiceManager = new SystemServiceManager(mSystemContext);
// SystemServiceManager
public class SystemServiceManager {
SystemServiceManager(Context context) {
mContext = context;
}
}
2.2.3、啓動引導服務
SystemServer調用startBootstrapServices()方法去啓動一系列的引導服務,如ActivityManagerService、PackageManagerService等;
private void startBootstrapServices() {
...
// 啓動AMS
mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
...
// 啓動PMS
mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
...
}
2.2.4、啓動核心服務
啓動核心服務,如電量管理服務、WebViewUpdateService等;
private void startCoreServices() {
...
mSystemServiceManager.startService(BatteryService.class);
...
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
traceBeginAndSlog("StartWebViewUpdateService");
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
traceEnd();
}
...
}
2.2.5、啓動其他服務
調用startOtherServices()方法創建其他服務,如NetworkManagementService、WindowManagerService、InputManagerService等;
並且在該方法中會執行ActivityManagerService的systemReady()方法,通過調用該方法會啓動Launcher進程,即桌面App,桌面本身就是一個App進程;
private void startOtherServices() {
...
try {
networkManagement = NetworkManagementService.create(context);
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
}
...
// WMS
wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
...
}
2.2.6、Looper循環消息
創建了主線程Looper,並執行loop()函數開啓消息輪訓等待消息到來;