Android系統啓動分析(三)

本節是本系列文章的第三篇,將分析System_Server進程的啓動過程和Launcher的啓動過程。

第一篇文章:Android系統啓動分析(一)
第二篇文章:Android系統啓動分析(二)

本節涉及到的文件有:

文件 路徑
ZygoteInit.java frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
ZygoteServer.java frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
AndroidRuntime.cpp frameworks/base/core/jni/AndroidRuntime.cpp
app_main.cpp frameworks/base/cmds/app_process/app_main.cpp
RuntimeInit.cpp frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
SystemServer.java frameworks/base/core/java/com/android/server/SystemServer.java
SystemServiceManager.java frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

三、SystemServer進程啓動

在上節講到了從Zygote進程啓動SystemServer進程,本節將分析SystemServer進程的啓動過程。

3.1 ZygoteInit.forkSystemServer

我們再來回顧下創建SystemServer的過程。

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
		ZygoteServer zygoteServer) {
	//準備一些啓動參數
	……
	try {
		……
		//註釋1:調用Zygote.forkSystemServer()
		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,當前代碼邏輯運行在子進程中
	if (pid == 0) {
		//如果有第二個Zygote,則等待第二個Zygote連接
		if (hasSecondZygote(abiList)) {
			waitForSecondaryZygote(socketName);
		}
		//註釋2:關閉Zygote進程創建的Socket
		zygoteServer.closeServerSocket();
		//註釋3:處理SystemServer進程
		return handleSystemServerProcess(parsedArgs);
	}
	return null;
}

該部分涉及到SystemServer進程創建的主要是註釋1、3兩處。首先Zygote會通過forkSystemServer方法來創建一個新的進程啓動SystemServer,同時返回進程pid,若pid==0,會調用handleSystemServerProcess處理SystemServer進程。在上節提到,forkSystemServer最終會調用nativeForkSystemServer()來處理,這裏不會細說。
註釋2處:由Zygote創建的子進程默認擁有Zygote進程的Socket對象,而子進程用不上,所以這裏調用了closeServerSocket來關閉Socket。

3.1.1 handleSystemServerProcess

我們重點關注handleSystemServerProcess方法。

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
	……
	if (parsedArgs.niceName != null) {
		//設置進程名字爲niceName:system_server
		Process.setArgV0(parsedArgs.niceName);
	}
    //註釋1
	//system/framework/{services.jar,ethernet-service.jar,wifi-service.jar}
	final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
	if (systemServerClasspath != null) {
		//註釋2:執行dex優化
		performSystemServerDexOpt(systemServerClasspath);
		……
	}

	if (parsedArgs.invokeWith != null) {
		……
	} else {
		ClassLoader cl = null;
		if (systemServerClasspath != null) {
			//註釋3:創建類加載器並賦予當前線程
			cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
			Thread.currentThread().setContextClassLoader(cl);
		}
		//註釋4
		return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
	}
}

註釋1處:systemServerClasspath路徑爲:/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar
註釋2處:調用performSystemServerDexOpt對註釋1處幾個jar包執行dex優化
註釋3處:創建類加載器並賦予當前線程
註釋4處:將啓動SystemServer的參數解析後的剩餘參數"com.android.server.SystemServer"保存到parsedArgs.remainingArgs,並傳入ZygoteInit.zygoteInit()中

3.1.2 ZygoteInit.zygoteInit

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
	//初始化Android Log輸出流,重定向System.out和System.err到Android Log
	RuntimeInit.redirectLogStreams();
	//註釋1:初始化通用的運行環境
	RuntimeInit.commonInit();
	//註釋2:通過JNI初始化Zygote
	ZygoteInit.nativeZygoteInit();
	//註釋3:應用初始化
	return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

註釋1處:初始化通用運行環境,如設置默認的未捕捉異常的Handler,設置時區,重置Log配置等
重點看看註釋2處:ZygoteInit.nativeZygoteInit()和註釋3處:RuntimeInit.applicationInit()

3.1.3 啓動Binder線程池

frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}
frameworks/base/cmds/app_process/app_main.cpp
void onZygoteInit(){
	sp<ProcessState> proc = ProcessState::self();
	proc->startThreadPool(); //啓動新的binder線程
}

該處代碼主要工作是打開"/dev/binder"設備節點,並啓動一個新的binder線程,這樣SystemServer進程就可以使用Binder進行進程間通信。

3.1.4 RuntimeInit.applicationInit

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {
	//設置關閉應用程序是否調用AppRuntime.onExit()
	nativeSetExitWithoutCleanup(true);
	//設置虛擬機堆內存利用率爲0.75
	VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
	VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
	final Arguments args = new Arguments(argv);
	//註釋1
	return findStaticMain(args.startClass, args.startArgs, classLoader);
}

註釋1處:調用findStaticMain()反射獲取到SystemServer的main()方法

private static Runnable findStaticMain(String className, String[] argv,
		ClassLoader classLoader) {
	Class<?> cl;

	try {
        //反射得到SystemServer類
		cl = Class.forName(className, true, classLoader);
	} catch (ClassNotFoundException ex) {
	}
    
	Method m;
	try {
        //反射獲取SystemServer.main()方法
		m = cl.getMethod("main", new Class[] { String[].class });
	} catch (NoSuchMethodException ex) {
	} catch (SecurityException ex) {
	}

	int modifiers = m.getModifiers();
	if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
	}
    
	return new MethodAndArgsCaller(m, argv);
}

該處主要作用是先反射得到SystemServer類並獲取其main方法,將其傳給MethodAndArgsCaller,並返回。MethodAndArgsCaller是一個Runnale實現類,其run()方法裏反射調用傳進去的Method,在這裏就是SystemServer.main()方法,最後run()在ZygoteInit.main()中調用。

3.2 解析SystemServer

frameworks/base/core/java/com/android/server/SystemServer.java
public static void main(String[] args) {
	new SystemServer().run();
}

SystemServer的main方法做的事很簡單,只是調用了SystemServer().run()

private void run() {
	try {
		//初始化時區
		//變更虛擬機的庫文件
		SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
		……
		//創建消息Looper
		Looper.prepareMainLooper();
		//加載android_servers.so庫
		System.loadLibrary("android_servers");
		……
		//初始化系統Context
		createSystemContext();

		//創建SystemServiceManager
		mSystemServiceManager = new SystemServiceManager(mSystemContext);
		……
		LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
		//準備線程池
		SystemServerInitThreadPool.get();
	} finally {
	}
	// Start services.
	try {
		//啓動引導服務
		startBootstrapServices();
		//啓動核心服務
		startCoreServices();
		//啓動其他服務
		startOtherServices();
		SystemServerInitThreadPool.shutdown();
	} catch (Throwable ex) {
		throw ex;
	} finally {
	}
	……
	// Loop forever.
	Looper.loop();
	throw new RuntimeException("Main thread loop unexpectedly exited");
}

SystemServer.run方法創建了一個SystemServiceManager對象,並將其加到LocalServices中,其內部有一個ArrayMap用來保存添加的服務。
startBootstrapServices()、startCoreServices()和startOtherServices()分別用來啓動引導服務、核心服務和其他服務。

3.2.1 startBootstrapServices

private void startBootstrapServices() {
	Installer installer = mSystemServiceManager.startService(Installer.class);
	……
	mActivityManagerService = mSystemServiceManager.startService(
			ActivityManagerService.Lifecycle.class).getService();
	mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
	mActivityManagerService.setInstaller(installer);

	mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
	mActivityManagerService.initPowerManagement();

	mSystemServiceManager.startService(LightsService.class);
	
	mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
	mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
	mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
	mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
	……
}

從上面可以看出,在startBootstrapServices裏面啓動了很多服務,如ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService等

3.2.2 startCoreServices

private void startCoreServices() {
	mSystemServiceManager.startService(DropBoxManagerService.class);
	mSystemServiceManager.startService(BatteryService.class);
	……
	mSystemServiceManager.startService(UsageStatsService.class);
	……
	mActivityManagerService.setUsageStatsManager(
			LocalServices.getService(UsageStatsManagerInternal.class));
	……
	mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}

startCoreServices中啓動了DropBoxManagerService、BatteryService、UsageStatsService、WebViewUpdateService等服務

3.2.3 startOtherServices

private void startOtherServices() {
    final Context context = mSystemContext;
	VibratorService vibrator = null;
	IStorageManager storageManager = null;
	NetworkManagementService networkManagement = null;
	NetworkStatsService networkStats = null;
	NetworkPolicyManagerService networkPolicy = null;
	ConnectivityService connectivity = null;
	NetworkScoreService networkScore = null;
	NsdService serviceDiscovery= null;
	WindowManagerService wm = null;
	SerialService serial = null;
	NetworkTimeUpdateService networkTimeUpdater = null;
	CommonTimeManagementService commonTimeMgmtService = null;
	InputManagerService inputManager = null;
	TelephonyRegistry telephonyRegistry = null;
	ConsumerIrService consumerIr = null;
	MmsServiceBroker mmsService = null;
	HardwarePropertiesManagerService hardwarePropertiesService = null;
	FaceIdManagerService faceIdService = null;
	……
}

startOtherServices啓動的服務較多,且邏輯與上述兩個方法相似,便不再分析。

3.2.4 系統服務的啓動

從3.2節可以看到,系統服務的啓動一般都是通過SystemServiceManager.startService來完成。這裏以ActivityManagerService的啓動來分析。

mActivityManagerService = mSystemServiceManager.startService(
			ActivityManagerService.Lifecycle.class).getService();

ActivityManagerService通過SystemServiceManager.startService來啓動,startService方法如下所示:

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public <T extends SystemService> T startService(Class<T> serviceClass) {
	try {
		final String name = serviceClass.getName();
		if (!SystemService.class.isAssignableFrom(serviceClass)) {
			……
		}
		final T service;
		try {
            //獲取類的構造器
			Constructor<T> constructor = serviceClass.getConstructor(Context.class);
			service = constructor.newInstance(mContext);
		} catch (InstantiationException ex) {
			……
		} catch (IllegalAccessException ex) {
			……
		} catch (NoSuchMethodException ex) {
			……
		} catch (InvocationTargetException ex) {
			……
		}
        //將service傳給startService
		startService(service);
		return service;
	} finally {
		……
	}
}

該方法先獲取到ActivityManagerService.LiftCycle的構造,再構造出一個LiftCycle的對象,最後將LiftCycle的對象傳給重載方法startService(final SystemService service)

public void startService(@NonNull final SystemService service) {
	//註釋1
	mServices.add(service);
	long time = SystemClock.elapsedRealtime();
	try {
        //註釋2
		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");
}

註釋1處:將service對象添加到mServices中,mServices是一個存儲SystemService的ArrayList,其定義如下:

private final ArrayList mServices = new ArrayList();

註釋2處:回調ActivityManagerService.LiftCycle對象的onStart方法完成啓動ActivityManagerService

3.3 SystemServer進程總結

SystemService進程是Android中一個很重要的進程,由Zygote進啓動,其啓動過程中主要做了如下工作:

  1. 初始化一些系統變量和運行環境
  2. 啓動Binder線程池
  3. 創建消息Looper、加載類庫、初始化系統Context、創建SystemServiceManager等
  4. 啓動各種系統服務

參考

https://blog.csdn.net/hongbochen1223/article/details/56331690
https://juejin.im/post/5aaf125d6fb9a028db587c50
https://blog.csdn.net/itachi85/article/details/54783506
https://blog.csdn.net/zhonglunshun/article/details/78615980
https://juejin.im/post/59f4592e51882529405991cb#heading-6
https://blog.csdn.net/qq_30993595/article/details/82747738
SystemServer進程啓動流程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章