[Android]Android系統啟動流程源碼分析



以下內容為原創,歡迎轉載,轉載請注明
來自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html

Android系統啟動流程源碼分析

首先我們知道,Android是基於Linux的,當Linux內核加載完成時就會自動啟動一個init的進程。
又因為我們每當我們啟動一個App時,就會生成一個新的dalvik實例,並處於一個新的進程(當然一個App也可能是多進程的)。
當我們打開第一個App的時候,就會通過init進程fork出一個zygote進程。之后打開新的App的時候都會fork之前的zygote進程。

fork一個zygote進程時,會進入com.android.internal.os.ZygoteInitmain方法進行初始化操作:

  • 預加載資源
// ...
preloadClasses();
preloadResources();
preloadOpenGL();
preloadSharedLibraries();
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
// ...
  • 從第一個zygote進程forkSystemServer進程,這個進程提供各種ManagerService
startSystemServer(abiList, socketName);

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
	int pid;
	// ...
	String args[] = {
            "--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",
        };
    /* Request to fork the system server process */
    pid = Zygote.forkSystemServer(
            parsedArgs.uid, parsedArgs.gid,
            parsedArgs.gids,
            parsedArgs.debugFlags,
            null,
            parsedArgs.permittedCapabilities,
            parsedArgs.effectiveCapabilities);
        // ...
}
  • Fork完SystemServer進程之后,繼續接下來在handleSystemServerProcess方法中傳入參數到SystemServer
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);

注意,這里傳入的參數是forkSystemServer進程后剩下的參數(parsedArgs.remainingArgs),其實只剩下了com.android.server.SystemServer這個參數了。

接下來繼續調用applicationInit ,傳入參數:

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
	final Arguments args;
	// ...
	args = new Arguments(argv);
	// ...
}

解析成Arguments后,得到了一個startClass對象,這個startClass其實就是剛剛的那個com.android.server.SystemServer

接下來,繼續調用 invokeStaticMain

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
	Class<?> cl;
	// ...
	cl = Class.forName(className, true, classLoader);
	// ...
	m = cl.getMethod("main", new Class[] { String[].class });
	// ...
	throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

就是調用通過反射得到com.android.server.SystemServer(也就是上面的startClass)的main(argv[])方法,然后手動拋一個攜帶了這個main(argv[])方法的MethodAndArgsCaller異常,但是這個異常是在ZygoteInit.main()方法中被catch,然后去調用它的run()方法,當然這個run()方法中會再去通過反射調用攜帶的main()方法(這個繞法真是有點坑爹--。):

public static class MethodAndArgsCaller extends Exception implements Runnable {
	// ...
	public void run() {
		// ...
	    mMethod.invoke(null, new Object[] { mArgs });
		// ...
	}
	// ...
}

繞了這么一大圈,終於通過MethodAndArgsCaller調用SystemServermain()方法了,代碼很簡單,直接new了之后run

new SystemServer().run();

接着,我們看SystemServerrun方法:

// ... (省略初始化當前的language、locale、country、指紋、用戶等信息的初始化准備工作)
// 設置當前進程設置優先級為THREAD_PRIORITY_FOREGROUND(-2)
android.os.Process.setThreadPriority(
    android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// 初始化主線程Looper
Looper.prepareMainLooper();
// ...
// 啟動消息循環
Looper.loop()

然后調用createSystemContext()方法創建初始化system context,這個待會再展開。

創建SystemServiceManager

mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

使用SystemServiceManager去通過以下方法創建啟動各個Service

  1. startBootstrapServices():
  • com.android.server.pm.Installer:提供安裝、卸載App等服務
  • com.android.server.am.ActivityServiceManager:提供Activity等組件的管理的服務,這個比較復雜暫且再挖個坑。
  • com.android.server.power.PowerManagerService:電源管理的服務。
  • com.android.server.lights.LightsService:LED管理和背光顯示的服務。
  • com.android.server.display.DisplayManagerService:提供顯示的生命周期管理,根據物理顯示設備當前的情況決定顯示配置,在狀態改變時發送通知給系統和應用等服務。
  • com.android.server.pm.PackageManagerService:管理所有的.apk
  • com.android.server.pm.UserManagerService:提供用戶相關服務。
  • 通過startSensorService()本地方法啟動Sensor服務。
  1. startCoreServices();
  • com.android.server.BatteryService:電量服務,需要LightService
  • com.android.server.usage.UsageStatsService:提供收集統計應用程序數據使用狀態的服務。
  • com.android.server.webkit.WebViewUpdateService:私有的服務(@hide),用於WebView的更新。
  1. startOtherServices();
  • com.android.server.accounts.AccountManagerService:提供所有賬號、密碼、認證管理等等的服務。
  • com.android.server.content.ContentService:用戶數據同步的服務。
  • com.android.server.VibratorService:震動服務。
  • IAlarmManager:提醒服務。
  • android.os.storage.IMountService:存儲管理服務。
  • com.android.server.NetworkManagementService:系統網絡連接管理服務。
  • com.android.server.net.NetworkStatsService:收集統計詳細的網絡數據服務。
  • com.android.server.net.NetworkPolicyManagerService:提供低網絡策略規則管理服務。
  • com.android.server.ConnectivityService:提供數據連接服務。
  • com.android.server.NetworkScoreServiceandroid.net.NetworkScoreManager的備份服務。
  • com.android.server.NsdService:網絡發現服務(Network Service Discovery Service)。
  • com.android.server.wm.WindowManagerService:窗口管理服務。
  • com.android.server.usb.UsbService:USB服務。
  • com.android.server.SerialService:串口服務。
  • com.android.server.NetworkTimeUpdateService:網絡時間同步服務。
  • com.android.server.CommonTimeManagementService:管理本地常見的時間配置的服務,當網絡配置變化時會重新配置本地服務。
  • com.android.server.input.InputManagerService:事件傳遞分發服務。
  • com.android.server.TelephonyRegistry:提供電話注冊管理的服務。
  • com.android.server.ConsumerIrService:遠程控制服務。
  • com.android.server.audio.AudioService:音量、鈴聲、聲道等管理服務。
  • com.android.server.MmsServiceBrokerMmsService的代理,因為MmsService運行在電話進程中,可能隨時crash,它會通過一個connectionMmsService建立一個橋梁,MmsService實現了公開的SMS/MMS的API。
  • TelecomLoaderService
  • CameraService
  • AlarmManagerService
  • BluetoothService
  • 還有其它很多很多Service,這方法竟然有近1000行……

startOtherServices()方法的最后:

mActivityManagerService.systemReady(new Runnable() {
	@Override
	public void run() {
		// 下面仍然是各種Service的啟動...
	}
}

調用這個方法用來告訴ActivityManagerService,此時可以運行第三方的代碼了(注意:這里的Home界面、Launcher等內置的App也算是第三方的App)。

public void systemReady(final Runnable goingCallback) {
	// ...
	if (mSystemReady) {
		// 回調到SystemServer,繼續啟動各種Service
		if (goingCallback != null) {
		    goingCallback.run();
		}
		return;
	}
	// ...

	ResolveInfo ri = mContext.getPackageManager().resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
	// ...
	ActivityInfo ai = ri.activityInfo;
	ApplicationInfo app = ai.applicationInfo;
	// ...從PackageManager中獲取要打開的HomeActivity
	mTopComponent = new ComponentName(app.packageName, ai.name);
	// ...
	// 啟動第一個Home界面
	startHomeActivityLocked(mCurrentUserId, "systemReady");

	// ...
	// 廣播通知啟動完成
	broadcastIntentLocked(/*...*/, mCurrentUserId);
	broadcastIntentLocked(/*...*/, UserHandle.USER_ALL);
	// ...
}

啟動Home界面的startHomeActivityLocked方法,調用mStackSupervisor啟動HomeActivity

boolean startHomeActivityLocked(int userId, String reason) {
	// ...
	Intent intent = getHomeIntent();
	// ...
	intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
	mStackSupervisor.startHomeActivity(intent, aInfo, reason);
	// ...
}

Intent getHomeIntent() {
	Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
	// 設置前面獲取到的mTopComponent
	intent.setComponent(mTopComponent);
	// ...
	intent.addCategory(Intent.CATEGORY_HOME);
	// ...
}

到此為止,SystemServer start完畢,並且啟動了Home界面。



然后我們再回過頭去看看在我們前面創建系統級的ContextcreateSystemContext)的時候做了什么:

ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);

首先調用了ActivityThread的靜態方法systemMain()

public static ActivityThread systemMain() {
	// ...
    ActivityThread thread = new ActivityThread();
    thread.attach(true);
    return thread;
}

創建一個ActivityThread,然后調用它的attach()方法:

thread.attach(true);

private void attach(boolean system) {
	if (!system) {
		// ...
	}else{
		// ...
		mInstrumentation = new Instrumentation();
        ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
        mInitialApplication = context.mPackageInfo.makeApplication(true, null);
        mInitialApplication.onCreate();
		// ...
	}
}

參數system表示,是否是系統級的線程,現在我們是啟動整個Android系統,顯然當前傳入的參數為true。所以進入else,首先,創建一個InstrumentationInstrumentation是什么?暫時先挖個坑。接着通過System Context創建一個ContextImpl,然后使用它的LoadedApk::makeApplication方法來創建整個應用的Application對象,然后調用ApplicationonCreate方法。

然后看下LoadedApk::makeApplication方法的實現:

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
	// 只有第一次調用makeApplication才會往下執行
	if (mApplication != null) {
	    return mApplication;
    }
    // 初始化系統的Application,所以appClass是"android.app.Application"
	String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }
	// ...
	ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);
    appContext.setOuterContext(app);
	// ...	
}

創建appContext,然后通過Instrumentation生成Application對象,並給appContext設置外部引用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM