com.android.server.am.ActivityManagerService
本文在 API 27 基礎(chǔ)上展開分析。
文章篇幅的長度與附上的代碼量有關(guān)希痴,請耐心查看。
沒時間的小伙伴春感,可以先大概瀏覽砌创,有一個感性認(rèn)識,后續(xù)再進(jìn)行研究鲫懒。
本文也是參考學(xué)習(xí)嫩实,如有錯誤,歡迎指正~
本文分析AMS啟動過程的主要流程窥岩,并非全部甲献。
有針對性和選擇性的分析AMS的相關(guān)代碼,非AMS的暫不討論颂翼。
為防止深入代碼導(dǎo)致記憶混亂晃洒,采用 step
標(biāo)識跟進(jìn),例如 step 1
朦乏,step 1.1
锥累,step 1.1.1
標(biāo)識從某個方法入口依次跟進(jìn)。
摘要
AMS - ActivityManagerService 集歇,是 Android 最核心 的服務(wù)桶略,主要負(fù)責(zé)系統(tǒng)中 四大組件 的啟動、切換、調(diào)度及應(yīng)用程序的管理和調(diào)度等工作际歼。
AMS通信結(jié)構(gòu)如下圖所示:
關(guān)鍵詞
- AMS:ActivityManagerService 惶翻;PMS-PackageManagerService;
- 系統(tǒng)服務(wù)鹅心;普通應(yīng)用吕粗;Client / Service 思想;
- Application旭愧;ApplicationInfo颅筋;
- SystemServiceManager;ServiceManager输枯;LocalServices议泵;
AMS啟動過程
為使讀者對AMS啟動有明確的方向,先將大致流程拋出來桃熄,方便整體把控先口。
- 創(chuàng)建出
SystemServer
進(jìn)程的 Android 運行環(huán)境 -
AMS
的初始化和啟動 - 將
SystemServer
進(jìn)程納入到AMS
的管理體系 -
AMS
啟動完成的后續(xù)工作
前提 已知
Zygote
創(chuàng)建fork
出的第一個 java 進(jìn)程是SystemServer
。- 每個進(jìn)程的入口是
main
函數(shù)瞳收。
com.android.internal.os.Zygote
public static void main(String argv[]) {
...
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
...
}
整個過程從 SystemServer
進(jìn)程的入口開始分析碉京,涉及 AMS
啟動主要過程的偽代碼如下:
com.android.server.SystemServer
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
...
// Initialize native services.
System.loadLibrary("android_servers");
...
// Initialize the system context.
// systemServer在啟動任何服務(wù)之前,先調(diào)用了createSystemContext 創(chuàng)建出 mSystemContext
// step 1
createSystemContext();
// Create the system service manager.
// SystemServiceManager 負(fù)責(zé)啟動所有的 系統(tǒng)服務(wù)
// mSystemContext 構(gòu)造出 SystemServiceManager螟深,
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
// LocalServices 管理當(dāng)前進(jìn)程的服務(wù)
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
} finally {
....
}
// Start services.
try {
...
// step 2 啟動引導(dǎo)服務(wù)谐宙,在其中創(chuàng)建并啟動AMS
startBootstrapServices();
...
// step 3 啟動其他服務(wù),在其中AMS注冊了SettingsProvider和其他后續(xù)工作
startOtherServices();
...
} catch (Throwable ex) {
...
} finally {
...
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Step 1 createSystemContext()
創(chuàng)建出 SystemServer
進(jìn)程的 Android 運行環(huán)境
com.android.server.SystemServer
private void createSystemContext() {
// step 1.1 調(diào)用ActivityThread的systemMain函數(shù)界弧,其中會創(chuàng)建出系統(tǒng)對應(yīng)的Context對象
ActivityThread activityThread = ActivityThread.systemMain();
// step 1.2 取出上面函數(shù)創(chuàng)建的Context對象凡蜻,保存在mSystemContext中
mSystemContext = activityThread.getSystemContext();
// 設(shè)置系統(tǒng)主題
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
...
}
Step 1.1 ActivityThread.systemMain()
調(diào)用 ActivityThread
的 systemMain()
函數(shù),其中會創(chuàng)建出系統(tǒng)對應(yīng)的 Context
對象
android.app.ActivityThread
public static ActivityThread systemMain() {
//雖然寫著ActivityManager夹纫,但和AMS沒有任何關(guān)系咽瓷,就是利用系統(tǒng)屬性和配置信息進(jìn)行判斷
if (!ActivityManager.isHighEndGfx()) {
//低版本關(guān)閉硬件渲染功能
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
// step 1.1.1 創(chuàng)建ActivityThread
ActivityThread thread = new ActivityThread();
//step 1.1.2 調(diào)用attach函數(shù),參數(shù)為true
thread.attach(true);
return thread;
}
ActivityThread
有自己的 main
入口函數(shù)舰讹,明確此處調(diào)用的是 systemMain()
茅姜。
ActivityThread#systemMain() 了解到主要功能有:
- 判斷是否開啟硬件加速。
- 創(chuàng)建
ActivityThread
對象月匣。 - 調(diào)用 thread 對象的
attach(true)
钻洒,注意參數(shù) system 傳入** true**。
Step 1.1.1 ActivityThread thread = new ActivityThread();
ActivityThread 的構(gòu)造函數(shù)比較簡單
com.android.app.ActivityThread
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
比較關(guān)鍵的是它內(nèi)部的成員變量锄开,
com.android.app.ActivityThread
public final class ActivityThread {
...
//定義了AMS與應(yīng)用通信的接口
final ApplicationThread mAppThread = new ApplicationThread();
//擁有自己的looper素标,說明ActivityThread確實可以代表事件處理線程
final Looper mLooper = Looper.myLooper();
//H繼承Handler,ActivityThread中大量事件處理依賴此Handler
final H mH = new H();
//用于保存該進(jìn)程的ActivityRecord
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>()
...
//用于保存進(jìn)程中的Service
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
...
//用于保存進(jìn)程中的Application
final ArrayList<Application> mAllApplications = new ArrayList<Application>();
...
}
ActivityThread
萍悴,是 Android Framework 中一個非常重要的類头遭,它代表應(yīng)用進(jìn)程的主線程寓免,其職責(zé)是調(diào)度及執(zhí)行在該線程中運行的四大組件。
在Android中
應(yīng)用進(jìn)程计维,指那些運行Apk的進(jìn)程袜香,它們有Zygote fork出來,其中運行著獨立的dalvik虛擬機鲫惶。
系統(tǒng)進(jìn)程蜈首,也應(yīng)用進(jìn)程相對,例如 Zygote 和 SystemServer欠母。其中SystemServer 也是由Zygote fork出來的欢策,也運行著一些系統(tǒng)Apk,例如framework-res.apk
赏淌、SettingsProvider.apk
等踩寇,該進(jìn)程也創(chuàng)建了主線程ActivityThread,所以SystemServer也可以看做是特殊的應(yīng)用進(jìn)程
對于上面提到的ActivityThread的成員變量猜敢,其用途基本上可以從名稱中得知姑荷,這里僅說明一下ApplicationThread盒延。
AMS負(fù)責(zé) 進(jìn)管理 和 進(jìn)程調(diào)度缩擂,因此 AMS 和應(yīng)用進(jìn)程之間通信需要 Binder機制。為此 Android 提供了一個 android.app.IApplicationThread 接口添寺,繼承 IInterface胯盯,該接口定義了 AMS 和應(yīng)用進(jìn)程之間的交互函數(shù)。例如:scheduleLaunchActivity
计露、scheduleCreateService
等
當(dāng) AMS 與應(yīng)用進(jìn)程通信時博脑,ApplicationThread 繼承 IApplicationThread.Stub 作為Binder通信的服務(wù)端。
step 1.1.2 thread.attach(true);
android.app.ActivityThread
//此時票罐,我們傳入的參數(shù)為true叉趣,表示該ActivityThread是**系統(tǒng)進(jìn)程的ActivityThread**
private void attach(boolean system) {
//創(chuàng)建出的ActivityThread保存在類的靜態(tài)變量sCurrentActivityThread
//AMS中的大量操作將會依賴于這個ActivityThread
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
// '應(yīng)用進(jìn)程' 的處理流程
...
} else {
// '系統(tǒng)進(jìn)程' 的處理流程,該情況只在SystemServer中處理
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
//設(shè)置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer進(jìn)程的名稱為“system_process”
android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());
try {
// 創(chuàng)建ActivityThread中的重要成員:
// Instrumentation该押、Application疗杉、Context
// step 1.1.2.1
mInstrumentation = new Instrumentation();
// step 1.1.2.3
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo); // step 1.1.2.2
// step 1.1.2.4
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
...
}
}
//以下系統(tǒng)進(jìn)程和非系統(tǒng)進(jìn)程均會執(zhí)行
...
//注冊Configuration變化的回調(diào)通知
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
//當(dāng)系統(tǒng)配置發(fā)生變化時(例如系統(tǒng)語言發(fā)生變化),回調(diào)該接口
...
}
...
});
}
系統(tǒng)進(jìn)程在ActivityThread的attach函數(shù)的主要工作:
- 創(chuàng)建Instrumentation
- 創(chuàng)建Context
Context是Android中的一個抽象類蚕礼,用于維護(hù)應(yīng)用運行環(huán)境的全局信息烟具。
通過Context可以訪問應(yīng)用的資源和類,甚至進(jìn)行系統(tǒng)級的操作奠蹬,例如啟動Activity朝聋、發(fā)送廣播等。 - 創(chuàng)建Application
step 1.1.2.1 new Instrumentation()
Instrumentation是Android中的一個工具類囤躁,當(dāng)該類被啟動時冀痕,它將優(yōu)先于其它的類被初始化荔睹。
此時,系統(tǒng)先創(chuàng)建它言蛇,再通過它創(chuàng)建其它組件应媚。
此外,系統(tǒng)和應(yīng)用組件之間的交互也將通過Instrumentation來傳遞猜极。
因此中姜,Instrumentation就能監(jiān)控系統(tǒng)和組件的交互情況了。
實際使用時,可以創(chuàng)建該類的派生類進(jìn)行相應(yīng)的操作徘键。
這個類在介紹啟動Activity的過程時還會碰到厕吉,此處不作展開。
step 1.1.2.2 getSystemContext()
android.app.ActivityThread
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
//調(diào)用ContextImpl的靜態(tài)函數(shù)createSystemContext
// step 1.1.2.2.1
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
step 1.1.2.2.1 ContextImpl.createSystemContext
android.app.ContextImpl
static ContextImpl createSystemContext(ActivityThread mainThread) {
// 創(chuàng)建LoadedApk類携龟,代表一個加載到系統(tǒng)中的APK
// 注意現(xiàn)在處于構(gòu)建Android運行環(huán)境階段,PMS服務(wù)還沒有啟動勘高,無法得到有效的Application峡蟋,后續(xù)PMS啟動后,后調(diào)用 LoadedApk.installSystemApplicationInfo 進(jìn)行填充
// 此時實例化的LoadedApk只是一個空殼华望,內(nèi)部使用空的Application
// step 1.1.2.2.1.1
LoadedApk packageInfo = new LoadedApk(mainThread);
//調(diào)用ContextImpl的構(gòu)造函數(shù)蕊蝗,參數(shù)中傳入了上面生成的對象packageInfo
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
// 初始化資源
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
createSystemContext的主要工作:
- 創(chuàng)建一個 LoadApk,代表一個加載到系統(tǒng)中的Apk
- 將傳入的線程參數(shù) mainThread 和 上一步生成的packageInfo 實例化一個ContextImpl對象
似乎沒有什么特別的赖舟,那么為什么函數(shù)名叫做 createSystemContext 蓬戚??
為了回答這個問題宾抓,就要看看LoadedApk的構(gòu)造函數(shù)
step 1.1.2.2.1.1
android.app.LoadApk
LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
mApplicationInfo = new ApplicationInfo();
//packageName為"android"
mApplicationInfo.packageName = "android";
mPackageName = "android";
//下面許多參數(shù)為null
...
}
注意到 mPackageName = "android"子漩,也就是 framework-res.apk。該Apk僅供SystemServer進(jìn)程使用石洗,因此上一步的方法名被定義成 createSystemContext幢泼。
又注意到,實例化了一個mApplicationInfo對象讲衫,但是只賦值了其中的packageName屬性缕棵,所以說現(xiàn)在的LoadedApk只是一個空殼。ApplicationInfo中包含了許多Apk重要信息焦人,當(dāng)之后的PMS啟動挥吵,完成對應(yīng)的解析后,AMS將重新調(diào)用 LoadedApk.installSystemApplicationInfo 進(jìn)行填充花椭。
step 1.1.2.3 ContextImpl.createAppContext
android.app.ContextImpl
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
createAppContext的工作比較簡單忽匈,利用 ActivityThread 和 LoadApk 構(gòu)造出 ContextImpl。
ContextImpl的構(gòu)造函數(shù)主要是完成了一些變量的初始化矿辽,建立起 ContextImpl 與 ActivityThread丹允、LoadApk郭厌、ContentResolver 之間的關(guān)系。
以后可以從 ContextImpl中 獲取一些變量雕蔽。
注意 createAppContext 和 上一步的 createSystemContext 中構(gòu)造 ContextImpl是一樣的
代碼簡單折柠,不再展開,注意在函數(shù)的最后建立和 ContentResolver 之間的聯(lián)系
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
step 1.1.2.4 context.mPackageInfo.makeApplication
先來看一下 Application 關(guān)系圖
Android中Application類用于保存應(yīng)用的全局狀態(tài)
Activity和Service都和具體的Application綁定在一起批狐,通過繼承關(guān)系可知扇售,每個Activity和Service均加入到Android運行環(huán)境中。
android.app.ActivityThread
private void attach(boolean system) {
...
// mPackageInfo是LoadApk類型嚣艇,從context中獲取LoadApk承冰,然后調(diào)用LoadApk的makeApplication函數(shù)
// step 1.1.2.4
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
// 調(diào)用Application的onCreate方法
mInitialApplication.onCreate();
...
}
android.app.LoadedApk
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
Application app = null;
String appClass = mApplicationInfo.className;
// 此流程 forceDefaultAppClass == true
if (forceDefaultAppClass || (appClass == null)) {
// 系統(tǒng)進(jìn)程中,對應(yīng)下面的appClass
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//實際上最后通過反射創(chuàng)建出Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
//一個進(jìn)程支持多個Application食零,mAllApplications用于保存該進(jìn)程中的Application對象
mActivityThread.mAllApplications.add(app);
mApplication = app;
// 此流程 instrumentation == null
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
// Rewrite the R 'constants' for all library apks.
...
return app;
}
makeApplication 的主要工作:
- 創(chuàng)建 framework-res.apk 對應(yīng)的Application
- 調(diào)用Application的onCreate函數(shù)
總結(jié) createSystemContext
至此困乒,createSystemContext函數(shù)介紹完畢。
當(dāng) SystemServer 調(diào)用 createSystemContext 完畢后:
- 得到一個 ActivityThread 對象贰谣,它代表當(dāng)前進(jìn)程(系統(tǒng)進(jìn)程)的主線程
- 得到一個 Context娜搂,對于 SystemServer 而言,它包含 Application 運行環(huán)境 和 framework-res.apk(名為"android"的LoadedAPK) 有關(guān)吱抚。
思考
Q:為什么啟動所有的服務(wù)前百宇,SystemServer先要調(diào)用createSystemContext?
A:眾所周知频伤,Android是以Java為基礎(chǔ)的恳谎,Java運行在進(jìn)程中芝此。
但是憋肖,Android想努力構(gòu)筑一個自己的運行環(huán)境,組件的運行和它們之間的交互均在該環(huán)境中實現(xiàn)婚苹。
createSystemContext
函數(shù)就是為* SystemServer系統(tǒng)進(jìn)程* 搭建一個和 普通應(yīng)用進(jìn)程 一樣的 Android環(huán)境岸更。
Android運行環(huán)境,是在進(jìn)程的基礎(chǔ)上構(gòu)建的膊升,但是把 進(jìn)程的概念被模糊化怎炊,所以應(yīng)用程序一般只和Android運行環(huán)境交互。
基于同樣的道理廓译,Android 希望 SystemServer進(jìn)程內(nèi)部運行的應(yīng)用评肆,也通過Android運行環(huán)境交互,因此才調(diào)用了 createSystemContext 函數(shù)非区。
創(chuàng)建Android運行環(huán)境時瓜挽,
由于SystemServer的特殊性,SystemServer.main() 調(diào)用了 ActivityThread.systemMain() 函數(shù)
對于普通的應(yīng)用程序征绸,將在自己的主線程匯中調(diào)用 ActivityThread.main() 函數(shù)
進(jìn)程 的 Android運行環(huán)境 涉及的主要類之間的關(guān)系如下圖久橙,其中核心類是ContextImpl 俄占,通過它可以得到 ContentResolver、系統(tǒng)資源Resources淆衷、應(yīng)用信息Application缸榄、當(dāng)前進(jìn)程的主線程ActivityThread、Apk信息LoadedApk等祝拯。
Step 2 AMS初始化
Step 1 創(chuàng)建完Android運行環(huán)境和創(chuàng)建系統(tǒng)服務(wù)管理后甚带,創(chuàng)建了SystemServiceManager,并將其加入到了 LocalServices 中佳头。
com.android.server.SystemServer
private void run() {
// Step 1
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
// Step 2
startBootstrapServices();
}
之后欲低,SystemServer
就調(diào)用了 startBootstrapServices
正式進(jìn)入AMS的創(chuàng)建和啟動過程。
偽代碼如下:
com.android.server.SystemServer
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class);
...
// Activity manager runs the show.
// 啟動AMS畜晰,然后獲取AMS保存到變量中
// Step 2.1
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//以下均是將變量存儲到AMS中
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
...
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mPackageManager = mSystemContext.getPackageManager();
...
// Set up the Application instance for the system process and get started.
// Step 2.2
mActivityManagerService.setSystemProcess();
...
mPackageManagerService.systemReady();
...
mActivityManagerService.systemReady(()->{ ... });
...
}
注意上面代碼 mSystemServiceManager 并沒有直接啟動 AMS 砾莱,而是啟動 AMS 的內(nèi)部類ActivityManagerService.Lifecycle
.
由于 AMS 并沒有繼承 SystemService
,因此不能通過 SystemServiceManager.startService()
直接啟動(內(nèi)部實現(xiàn)采用反射的方式)凄鼻,例如可以直接啟動Installer
腊瑟。
AMS 的內(nèi)部類 Lifecycle
繼承 SystemService
,像一個適配器來間接操作 AMS块蚌。讓 AMS 能夠 像 SystemService
一樣被 SystemServiceManager
通過反射的方式啟動闰非。
Lifecycle類簡單如下:
com.android.server.am.ActivityManagerService
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
// step 2.1.1 調(diào)用AMS的構(gòu)造函數(shù)
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
// step 2.1.2 調(diào)用AMS的start函數(shù)
mService.start();
}
@Override
public void onCleanupUser(int userId) {
mService.mBatteryStatsService.onCleanupUser(userId);
}
public ActivityManagerService getService() {
return mService;
}
}
Step 2.1.1 AMS 構(gòu)造函數(shù)
構(gòu)造函數(shù)較長但簡單,主要初始化了一些變量峭范,可以過一遍
public ActivityManagerService(Context systemContext) {
//AMS的運行上下文與SystemServer一致
mContext = systemContext;
............
//取出的是ActivityThread的靜態(tài)變量sCurrentActivityThread
//這意味著mSystemThread與SystemServer中的ActivityThread一致
mSystemThread = ActivityThread.currentActivityThread();
............
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
//處理AMS中消息的主力
mHandler = new MainHandler(mHandlerThread.getLooper());
//UiHandler對應(yīng)于Android中的UiThread
mUiHandler = new UiHandler();
if (sKillHandler == null) {
sKillThread = new ServiceThread(TAG + ":kill",
android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
sKillThread.start();
//用于接收消息财松,殺死進(jìn)程
sKillHandler = new KillHandler(sKillThread.getLooper());
}
//創(chuàng)建兩個BroadcastQueue,前臺的超時時間為10s纱控,后臺的超時時間為60s
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
//創(chuàng)建變量辆毡,用于存儲信息
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
mAppErrors = new AppErrors(mContext, this);
//這一部分,分析BatteryStatsService時提過甜害,進(jìn)行BSS的初始化
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.scheduleWriteToDisk();
mOnBattery = DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
mBatteryStatsService.getActiveStatistics().setCallback(this);
//創(chuàng)建ProcessStatsService舶掖,感覺用于記錄進(jìn)程運行時的統(tǒng)計信息,例如內(nèi)存使用情況尔店,寫入/proc/stat文件
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
//啟動Android的權(quán)限檢查服務(wù)眨攘,并注冊對應(yīng)的回調(diào)接口
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
new IAppOpsCallback.Stub() {
@Override public void opChanged(int op, int uid, String packageName) {
if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
if (mAppOpsService.checkOperation(op, uid, packageName)
!= AppOpsManager.MODE_ALLOWED) {
runInBackgroundDisabled(uid);
}
}
}
});
//用于定義ContentProvider訪問指定Uri對應(yīng)數(shù)據(jù)的權(quán)限,aosp中似乎沒有這文件
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
//創(chuàng)建多用戶管理器
mUserController = new UserController(this);
//獲取OpenGL版本
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
............
//資源配置信息置為默認(rèn)值
mConfiguration.setToDefaults();
mConfiguration.setLocales(LocaleList.getDefault());
mConfigurationSeq = mConfiguration.seq = 1;
//感覺用于記錄進(jìn)程的CPU使用情況
mProcessCpuTracker.init();
//解析/data/system/packages-compat.xml文件嚣州,該文件用于存儲那些需要考慮屏幕尺寸的APK的一些信息
//當(dāng)APK所運行的設(shè)備不滿足要求時鲫售,AMS會根據(jù)xml設(shè)置的參數(shù)以采用屏幕兼容的方式運行該APK
mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
//用于根據(jù)規(guī)則過濾一些Intent
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
//以下的類,似乎用于管理和監(jiān)控AMS維護(hù)的Activity Task信息
//ActivityStackSupervisor是AMS中用來管理Activity啟動和調(diào)度的核心類
mStackSupervisor = new ActivityStackSupervisor(this);
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
mRecentTasks = new RecentTasks(this, mStackSupervisor);
//創(chuàng)建線程用于統(tǒng)計進(jìn)程的CPU使用情況
mProcessCpuThread = new Thread("CpuTracker") {
@Override
public void run() {
while (true) {
try {
try {
//計算更新信息的等待間隔
//同時利用wait等待計算出的間隔時間
......
} catch(InterruptedException e) {
}
//更新CPU運行統(tǒng)計信息
updateCpuStatsNow();
} catch (Exception e) {
..........
}
}
}
};
//加入Watchdog的監(jiān)控
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
Step 2.1.2 AMS 的 start 函數(shù)
private void start() {
//完成統(tǒng)計前的復(fù)位工作
Process.removeAllProcessGroups();
//開始監(jiān)控進(jìn)程的CPU使用情況
mProcessCpuThread.start();
//注冊電池狀態(tài)服務(wù)
mBatteryStatsService.publish(mContext);
//注冊一些應(yīng)用信息和控制的服務(wù)该肴,比如權(quán)限等
mAppOpsService.publish(mContext);
// ActivityManagerInternal 是 activity manager 本地管理服務(wù)的接口
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
start() 函數(shù)的主要工作:
- 啟動CPU監(jiān)控線程情竹,該線程將會開始統(tǒng)計不同進(jìn)程使用CPU的情況
- 發(fā)布一些服務(wù),如BatteryStatsService沙庐、AppOpsService(權(quán)限管理相關(guān))和本地實現(xiàn)的LocalService繼承ActivityManagerInternal的服務(wù)
至此鲤妥,AMS 初始化完成
下一步將 SystemServer 納入AMS的管理體系
step 2.2 AMS#setSystemProcess
public void setSystemProcess() {
try {
// step 2.2.1 以下幾個向ServiceManager注冊幾個服務(wù)
// AMS自己佳吞,在這里注冊,以后通過ServiceManager獲取棉安,最常見的獲取key為"activity"的服務(wù)
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
//注冊進(jìn)程統(tǒng)計信息的服務(wù)
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
//用于打印內(nèi)存信息用的
ServiceManager.addService("meminfo", new MemBinder(this));
//用于輸出進(jìn)程使用硬件渲染方面的信息
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
//用于輸出數(shù)據(jù)庫相關(guān)的信息
ServiceManager.addService("dbinfo", new DbBinder(this));
//MONITOR_CPU_USAGE默認(rèn)為true
if (MONITOR_CPU_USAGE) {
//用于輸出進(jìn)程的CPU使用情況
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
//注冊權(quán)限管理服務(wù)
ServiceManager.addService("permission", new PermissionController(this));
//注冊獲取進(jìn)程信息的服務(wù)
ServiceManager.addService("processinfo", new ProcessInfoService(this));
// step 2.2.2 通過 PMS 查詢 package 名為 "android" 的應(yīng)用的ApplicationInfo底扳,即系統(tǒng)應(yīng)用
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
// step 2.2.3 通過查詢的結(jié)果進(jìn)行安裝
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
// step 2.2.4 以下與AMS的進(jìn)程管理
synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
AMS的setSystemProcess有四個主要功能:
- 向
ServiceManager
注冊服務(wù)統(tǒng)一管理,如 AMS 本身贡耽。 - 獲取
package
名為 "android" 的應(yīng)用的ApplicationInfo
衷模,即系統(tǒng)應(yīng)用framework-res.apk
。 - 調(diào)用
ActivityThread
的installSystemApplicationInfo
蒲赂,回憶之前創(chuàng)建的LoadedApk
是一個空殼阱冶,沒有實際的ApplicationInfo
。 - AMS 進(jìn)程管理相關(guān)的操作
step 2.2.1 注冊服務(wù) ServiceManager.addService()
com.android.server.am.ActivityManagerService # setSystemProcess()
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
注意平時常用的 AMS 獲取滥嘴,要知道是在這里進(jìn)行 添加 的木蹬。
Step 2.2.2 獲取系統(tǒng)應(yīng)用信息 getApplicationInfo
com.android.server.am.ActivityManagerService
public void setSystemProcess() {
ApplicationInfo info = mContext.getPackageManager() // Step 2.2.2.1
.getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); // Step 2.2.2.2
}
Step 2.2.2.1 mContext.getPackageManager()
Context 的實現(xiàn)類是 ContextImpl
android.app.ContextImpl
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
// 依賴于ActivityThread,此時為系統(tǒng)進(jìn)程的主線程若皱,調(diào)用ActivityThread的getPackageManager()函數(shù)
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
// 利用PMS的代理對象镊叁,構(gòu)建ApplicationPackageManager對象(繼承PackageManager)
// Note:PackageManager不繼承IPackageManager。IPackageManager繼承IInterface走触,屬于Binder接口
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
跟進(jìn)一下ActivityThread的getPackageManager:
android.app.ActivityThread
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
// 依賴于Binder通信晦譬,并通過ServiceManager獲取到PMS對應(yīng)的BpBinder
IBinder b = ServiceManager.getService("package");
//得到PMS對應(yīng)的Binder服務(wù)代理
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
從上面我們可以看到,獲取 PMS
用到了Binder通信互广。方式和獲取 AMS
一樣敛腌。
實際上,PMS
由 SystemServer
創(chuàng)建惫皱,與 AMS
運行在同一一個進(jìn)程像樊,且初始化比 AMS
早,但是比構(gòu)建 Android 運行環(huán)境晚逸吵,所以之前構(gòu)建的系統(tǒng) LoadedApk
是一個空殼凶硅,實際內(nèi)容需要從 PMS
中獲取。
實際上扫皱,AMS
完全可以不經(jīng)過 Context
、ActivityThread
捷绑、Binder
來獲取 PMS
韩脑,直接在 SystemServer
中取 mPackageManagerService
屬性即可
但是源碼通過 ActivityThread.getPackageManager
等之前和之后一系列操作獲取 PMS
的原因是:
讓 SystemServer
進(jìn)程中的服務(wù),也通過之前構(gòu)建的 Android 運行環(huán)境來交互粹污,保證了組件之間交互接口的統(tǒng)一段多,為未來的系統(tǒng)保留了可擴展性。
step 2.2.2.2 通過 PMS 獲取 getApplicationInfo()
得到 PMS
服務(wù)的代理對象后壮吩,AMS
調(diào)用 PMS
的getApplicationInfo
接口进苍,獲取 package
名為 "android" 的 ApplicationInfo
加缘。
在 AMS
的 setSystemProcess
被調(diào)用前,PMS
已經(jīng)啟動了觉啊。
在 PMS
的構(gòu)造函數(shù)中拣宏,它將解析手機中所有的AndroidManifest.xml
,然后形成各種數(shù)據(jù)結(jié)構(gòu)以維護(hù)應(yīng)用的信息杠人。
getApplicationInfo
就是通過 package
名勋乾,從對應(yīng)的數(shù)據(jù)結(jié)構(gòu)中取出對應(yīng)的應(yīng)用信息。這部分內(nèi)容主要就是查詢數(shù)據(jù)結(jié)構(gòu)的內(nèi)容嗡善,不作深入分析辑莫。
2.2.3 installSystemApplicationInfo
在上一步得到 framework-res.apk
的 ApplicationInfo
后,需要將該 ApplicationInfo
保存到 SystemServer
對應(yīng)的ActivityThread
中罩引。
com.android.server.am.ActivityMagerService
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
AMS
中的 mSystemThread
就是 SystemServer
中創(chuàng)建出的 ActivityThread
各吨。
跟進(jìn)一下 ActivityThread
的 installSystemApplicationInfo
函數(shù)
com.android.app.ActivityThread
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
//調(diào)用SystemServer中創(chuàng)建出的ContextImpl的installSystemApplicationInfo函數(shù)
getSystemContext().installSystemApplicationInfo(info, classLoader);
getSystemUiContext().installSystemApplicationInfo(info, classLoader);
// give ourselves a default profiler
// 創(chuàng)建一個Profiler對象,用于性能統(tǒng)計
mProfiler = new Profiler();
}
}
繼續(xù)跟進(jìn) ContextImpl
的 installSystemApplicationInfo
函數(shù)
com.android.app.ContextImpl
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
// mPackageInfo 的類型為 LoadedApk
mPackageInfo.installSystemApplicationInfo(info, classLoader);
}
繼續(xù)跟進(jìn) LoadedApk
的 installSystemApplicationInfo
函數(shù)
com.android.app.LoadedApk
/**
* Sets application info about the system package.
*/
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
// 這個接口僅供系統(tǒng)進(jìn)程調(diào)用袁铐,故這里斷言了一下
assert info.packageName.equals("android");
mApplicationInfo = info;
mClassLoader = classLoader;
}
至此绅你,我們知道了 installSystemApplicationInfo
的真相就是:
將包名為 "android" 對應(yīng)的 ApplicationInfo
(framework-res.apk
),加入到之前創(chuàng)建的系統(tǒng) LoadedApk
中(SystemServer#run#createSystemContext)
原因是:在此之前創(chuàng)建 SystemContext
時昭躺,PMS
還沒有執(zhí)行對手機中的文件進(jìn)行解析的操作忌锯,因此初始化的 LoadApk
并沒有持有有效的 ApplicationInfo
(僅實例化了一個空 ApplicationInfo
對象,設(shè)置了 packageName
屬性為"android"领炫,其他并沒有設(shè)置)偶垮。
在此基礎(chǔ)上,AMS
下一步的工作就呼之欲出了
因為 AMS
是專門用于進(jìn)程管理和調(diào)度的帝洪,但是framework.apk
運行在 SystemServer
進(jìn)程中似舵,所以SystemServer
進(jìn)程也應(yīng)該在 AMS
有對應(yīng)的管理結(jié)構(gòu)。(SystemServer
創(chuàng)建了 AMS
葱峡,但是 AMS
還想管理SystemServer
^ - ^ )
于是砚哗,AMS
的下一步工作就是將 SystemServer
的運行環(huán)境和一個進(jìn)程管理結(jié)構(gòu)對應(yīng)起來,并進(jìn)行統(tǒng)一的管理砰奕。
2.2.4 AMS進(jìn)程的管理
ProcessRecord
該類定義一個進(jìn)程的詳細(xì)信息
mLruProcess列表保存進(jìn)程
進(jìn)程對應(yīng)的oom_adj值將決定進(jìn)程是否被kill掉
AMS#setSystemProcess函數(shù)中蛛芥,進(jìn)程管理相關(guān)的代碼如下:
com.android.server.am.ActivityManagerServer
public void setSystemProcess() {
...
synchronized (this) {
// 創(chuàng)建進(jìn)程管理對應(yīng)的結(jié)構(gòu) ProcessRecord
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
// 由于此時創(chuàng)建的是SystemServer進(jìn)程對應(yīng)的ProcessRecord,因此設(shè)置了一些特殊值
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
// 將SystemServer對應(yīng)的ApplicationThread保存到ProcessRecord中
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
// 按pid將ProcessRecord保存到mPidsSelfLocked中
mPidsSelfLocked.put(app.pid, app);
}
// TODO 調(diào)整 mLruProcess 列表的位置军援,最近活動過的進(jìn)程總是位于前列仅淑,同時擁有Activity的進(jìn)程總是前于只有Service的進(jìn)程
updateLruProcessLocked(app, false, null);
// TODO 更新進(jìn)程對應(yīng)的oom_adj值,oom_adj將決定進(jìn)程是否被kill掉
updateOomAdjLocked();
}
...
}
這里我們僅分析一下創(chuàng)建進(jìn)程管理結(jié)構(gòu)的函數(shù)newProcessRecordLocked胸哥。
updateLruProcessLocked和updateOomAdjLocked函數(shù)比較復(fù)雜涯竟,等對AMS有更多的了解后,再做分析。
com.android.server.am.ActivityManagerServer
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid) {
//進(jìn)程的名稱
String proc = customProcess != null ? customProcess : info.processName;
//將用于創(chuàng)建該進(jìn)程的電源統(tǒng)計項
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
final int userId = UserHandle.getUserId(info.uid);
//isolated此時為false
if (isolated) {
...
}
//創(chuàng)建出對應(yīng)的存儲結(jié)構(gòu)
final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
//判斷進(jìn)程是否常駐
if (!mBooted && !mBooting
&& userId == UserHandle.USER_SYSTEM
&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
r.persistent = true;
}
//按進(jìn)程名將ProcessRecord存入到AMS的變量mProcessNames中
//該變量的類型為ProcessMap<ProcessRecord>
//結(jié)合前面的代碼庐船,我們知道AMS有兩種方式可以取到ProcessRecord银酬,一是根據(jù)進(jìn)程名,二是根據(jù)進(jìn)程名稱
addProcessNameLocked(r);
return r;
}
跟進(jìn)一下 ProcessRecord
的構(gòu)造函數(shù)
com.android.server.am.ProcessRecord
ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
String _processName, int _uid) {
mBatteryStats = _batteryStats; //用于電量統(tǒng)計
info = _info; //保存ApplicationInfo
...........
processName = _processName; //保存進(jìn)程名
//一個進(jìn)程能運行多個Package筐钟,pkgList用于保存package名
pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));
//以下變量和進(jìn)程調(diào)度優(yōu)先級有關(guān)
maxAdj = ProcessList.UNKNOWN_ADJ;
curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
//決定進(jìn)程是否常駐內(nèi)存(即使被殺掉揩瞪,系統(tǒng)也會重啟它)
persistent = false;
removed = false;
lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
}
總結(jié)
AMS#setSystemProcess
函數(shù)主要完成任務(wù):
- 向
ServiceManager
添加注冊了一些服務(wù),包括AMS
自身盗棵。 - 通過
PMS 獲取
"android" 系統(tǒng)服務(wù)的ApplicationInfo
信息壮韭,并安裝到系統(tǒng)服務(wù)對應(yīng)的LoadedApk
中。 - 構(gòu)建
SystemServer
進(jìn)程對應(yīng)的ProcessRecord
纹因,將SystemServer
納入到AMS
的管理中喷屋。
Step 3 SystemServer#startOtherServices
接下來AMS啟動相關(guān)的操作,在SystemServer的startOtherServices函數(shù)中
com.android.server.SystemServer
private void startOtherServices() {
...
// Step 3.1
mActivityManagerService.installSystemProviders();
...
// Step 3.2
mActivityManagerService.systemReady(new Runnable() {
...
});
}
繼續(xù)跟進(jìn)AMS的installSystemProviders函數(shù)
Step 3.1 AMS # installSystemProviders
com.android.server.am.ActivityManagerServer
public final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (this) {
// AMS 根據(jù)進(jìn)程名取出對應(yīng)的ProcessRecord
ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
// 得到該ProcessRecord對應(yīng)的ProviderInfo
// Step 3.1.1
providers = generateApplicationProvidersLocked(app);
// 僅處理系統(tǒng)級的Provider瞭恰,取出非系統(tǒng)
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Not installing system proc provider " + pi.name
+ ": not system .apk");
providers.remove(i);
}
}
}
}
if (providers != null) {
// 安裝Provider
// Step 3.1.2
mSystemThread.installSystemProviders(providers);
}
mConstants.start(mContext.getContentResolver());
// 監(jiān)控Settings數(shù)據(jù)庫中的secure屯曹、System和Global表的變化
mCoreSettingsObserver = new CoreSettingsObserver(this);
// 創(chuàng)建監(jiān)控數(shù)據(jù)庫中字體大小的變化
mFontScaleSettingObserver = new FontScaleSettingObserver();
// Now that the settings provider is published we can consider sending
// in a rescue party.
RescueParty.onSettingsProviderPublished(mContext);
//mUsageStatsService.monitorPackages();
}
從上面的代碼可以看出,AMS # installSystemProviders
主要是加載運行在 SystemServer
進(jìn)程中的 ContentProvider
惊畏,即SettingProvider.apk
(frameworks/base/packages/SettingsProvider)
framework-res.apk 源碼的位置:frameworks/base/core/res
SettingProvider.apk 源碼的位置:frameworks/base/packages/SettingsProvider
上面有兩個比較重要的函數(shù):
-
generateApplicationProvidersLocked
返回一個進(jìn)程對應(yīng)的ProviderInfo
列表恶耽。 -
ActivityThread
可以看做進(jìn)程Android運行環(huán)境,因此它的installSystemProviders
表示為對應(yīng)進(jìn)程安裝ContentProvider
颜启。 - 當(dāng)
SettingProvider
被加載到SystemServer
進(jìn)程中運行后偷俭,AMS
就注冊了兩個ContentObserver
監(jiān)控SettingsProvider
中的字段變化
AMS 監(jiān)控的字段影響范圍比較廣,例如字體發(fā)生變化時缰盏,很多應(yīng)用的顯示界面需要作出調(diào)整涌萤,這也許就是讓 AMS來 負(fù)責(zé)監(jiān)控這些字段的原因
接下來,我們看上面比較重要的兩個函數(shù)
Step 3.1.1
com.android.server.am.ActivityServiceManager
private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
List<ProviderInfo> providers = null;
try {
// 利用 PMS 根據(jù)進(jìn)程名及權(quán)限口猜,從數(shù)據(jù)結(jié)構(gòu)中得到進(jìn)程對應(yīng)的ProviderInfo
providers = AppGlobals.getPackageManager()
.queryContentProviders(app.processName, app.uid,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
| MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
.getList();
} catch (RemoteException ex) {
}
if (DEBUG_MU) Slog.v(TAG_MU,
"generateApplicationProvidersLocked, app.info.uid = " + app.uid);
int userId = app.userId;
if (providers != null) {
// 通常而言负溪,我們逐漸向容器加入數(shù)據(jù)時,容器只有在數(shù)據(jù)超出當(dāng)前存儲空間時
// 才會運行內(nèi)存的重新分配(一般乘2)和數(shù)據(jù)的拷貝
// 因此若待加入數(shù)據(jù)總量很大济炎,在逐步向容器加入數(shù)據(jù)的過程川抡,容器將會有多次重新分配和拷貝的過程
// 或許整體的開銷并不是很驚人,但事先將內(nèi)存一次分配到位须尚,體現(xiàn)了對極致的追求
// 建議學(xué)習(xí)
int N = providers.size();
app.pubProviders.ensureCapacity(N + app.pubProviders.size());
for (int i=0; i<N; i++) {
// TODO: keep logic in sync with installEncryptionUnawareProviders
ProviderInfo cpi =
(ProviderInfo)providers.get(i);
// 判斷是否為單例的
boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
cpi.name, cpi.flags);
// 針對多用戶的處理
// 若一個Provider是單例的崖堤,但當(dāng)前進(jìn)程不屬于默認(rèn)用戶,那么這個Provider將不被處理
// 簡單來說恨闪,就是兩個用戶都啟動一個進(jìn)程時(有了兩個進(jìn)程)
// 定義于進(jìn)程Package中單例的Provider僅運行在默認(rèn)用戶啟動的進(jìn)程中
if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
// This is a singleton provider, but a user besides the
// default user is asking to initialize a process it runs
// in... well, no, it doesn't actually run in this process,
// it runs in the process of the default user. Get rid of it.
providers.remove(i);
N--;
i--;
continue;
}
// 包名和類名組成ComponentName
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
// 創(chuàng)建ContentProvider對應(yīng)的ContentProviderRecord
// 加入到AMS的MProviderMap中
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
if (cpr == null) {
cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
mProviderMap.putProviderByClass(comp, cpr);
}
// 將ContentProviderRecord保存在ProcessRecord中
app.pubProviders.put(cpi.name, cpr);
if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
// 當(dāng)ContentProvider僅屬于當(dāng)前進(jìn)程時倘感,還需要統(tǒng)計該Provider的運行信息
app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
mProcessStats);
}
//通知PMS記錄該Provider對應(yīng)包被使用的時間
notifyPackageUse(cpi.applicationInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
}
}
return providers;
}
generateApplicationProvidersLocked
函數(shù)實現(xiàn)的主要功能:
- 從
PMS
中得到應(yīng)用對應(yīng)的ContentProvider
。 - 利用應(yīng)用信息和對應(yīng)的
ContentProvider
組成ContentProviderRecord
咙咽。 - 將
ContentProviderRecord
按包名保存到AMS
的mProviderMap
中。原因:AMS
需要管理淤年。ContentProvider
钧敞,當(dāng)一個進(jìn)程退出時蜡豹,AMS
需要將其中運行的ContentProvider
信息從系統(tǒng)中移除。 - 將
ContentProviderRecord
按包名保存到ProcessRecord
中溉苛。原因:最終需要落實到一個進(jìn)程中镜廉。
Step 3.1.2 ActivityThread # installSystemProviders
com.android.app.ActivityThread
public final void installSystemProviders(List<ProviderInfo> providers) {
if (providers != null) {
//對于SystemServer進(jìn)程而言,mInitialApplication是framework-res.apk對應(yīng)的Application
installContentProviders(mInitialApplication, providers);
}
}
####### Step 3.1.2.1 ActivityThread # installContentProviders
com.android.app.ActivityThread
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
...
// Step 3.1.2.1.1 初始化并保存ContentProvider
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
// Step 3.1.2.1.2 向AMS注冊ContentProvider
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
installContentProviders
是安裝 ContentProvider
的通用程序愚战,主要包括兩方面的工作:
- 調(diào)用
installProvider
得到ContentProviderHolder
對象娇唯,其間完成了對應(yīng)ContentProvider
的初始化等工作。 - 向
AMS
發(fā)布ContentProviderHolder
寂玲。
####### Step 3.1.2.1.1 ActivityThread # installProvider
com.android.app.ActivityThread
private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
ContentProvider localProvider = null;
IContentProvider provider;
if (holder == null || holder.provider == null) {
// 此時holder==null塔插,進(jìn)入這個分支
...
Context c = null;
ApplicationInfo ai = info.applicationInfo;
// 下面判斷的作用是:為待安裝的ContentProvider找到對應(yīng)的Application
// 在 AndroidManifest中,ContentProvider是Application的子標(biāo)簽拓哟,因此ContentPro與Application有一種對應(yīng)關(guān)系
// 本次流程中想许,傳入的context是mInitApplication,代表的是framework-res.apk
// 而 ai 是從ProviderInfo中獲取的断序,代表的是SettingProvider流纹,SettingProvider.apk所對應(yīng)的Application還未創(chuàng)建
// 所有進(jìn)入最后的else判斷中
if (context.getPackageName().equals(ai.packageName)) {
c = context;
} else if (mInitialApplication != null &&
mInitialApplication.getPackageName().equals(ai.packageName)) {
c = mInitialApplication;
} else {
try {
// 以下將重新創(chuàng)建一個Context,指向SettingProvider.apk
// ai.packageName = "com.android.provider.settings"
// createPackageContext方法中利用package對應(yīng)的LoadedApk信息违诗,創(chuàng)建新的ContextImpl
// 其內(nèi)部通過 mMainThread.getPackageInfo 取出LoadedApk漱凝,在這個過程中,如果已經(jīng)加載過就直接從存儲變量中取诸迟,否則同PMS重新構(gòu)建
c = context.createPackageContext(ai.packageName,
Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
}
}
...
try {
// 上面必須找到ContentProvider對應(yīng)的Context的原因:
// 1. ContentProvider和Application有對應(yīng)關(guān)系茸炒,而Application繼承Context
// 2. 只有正確的Context才能加載對應(yīng)APK的Java字節(jié)碼,從而通過反射創(chuàng)建出ContentProvider實例
// 得到對應(yīng)的ClassLoader
final java.lang.ClassLoader cl = c.getClassLoader();
// 反射創(chuàng)建實例
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
// ContentProvider的mTransport對象
// 變現(xiàn)類型為IContentProvider亮蒋,實際為ContentProviderNative扣典,即ContentProvider的Binder通信服務(wù)端BbBinder
// Tansport 繼承 ContentProviderNative
provider = localProvider.getIContentProvider();
...
// 初始化ContentProvider,內(nèi)部會調(diào)用ContentProvider的onCreate函數(shù)
localProvider.attachInfo(c, info);
} catch (java.lang.Exception e) {
...
return null;
}
} else {
provider = holder.provider;
...
}
ContentProviderHolder retHolder;
synchronized (mProviderMap) {
...
// 調(diào)用ContentProviderNative的asBinder慎玖,得到服務(wù)端的Binder對象
IBinder jBinder = provider.asBinder();
if (localProvider != null) {
ComponentName cname = new ComponentName(info.packageName, info.name);
ProviderClientRecord pr = mLocalProvidersByName.get(cname);
if (pr != null) {
...
provider = pr.mProvider;
} else {
// 根據(jù)ProviderInfo創(chuàng)建ContenProviderHolder
holder = new ContentProviderHolder(info);
// 使持有provider
holder.provider = provider;
holder.noReleaseNeeded = true;
// 構(gòu)造ProviderClientRecord贮尖,并按authority將其保存在mProviderMap中
pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
// 將 pr 按 jBinder 保存在 mLocalProviders 中
mLocalProviders.put(jBinder, pr);
// 將 pr 按 cname 保存在 mLocalProvidersByName 中
mLocalProvidersByName.put(cname, pr);
}
retHolder = pr.mHolder;
} else {
...
}
}
return retHolder;
}
installProvider
的代碼較長,但實際思想很簡單趁怔,就是環(huán)環(huán)相扣的三步:
- 創(chuàng)建出
ContentProvider
對應(yīng)的ContextImpl
(代表對應(yīng)的運行環(huán)境) - 利用
ContextImpl
得到對應(yīng)的ClassLoader
湿硝,完成ContentProvider
的初始化和啟動 - 得到與
ContentProvider
通信的BBinder
,然后按名稱和BBinder
润努,將ContentProvider
保存到對應(yīng)的存儲結(jié)構(gòu)中“
ActivityThread 與 ContenProvider 的關(guān)系大概如上圖所示关斜。
ContentProvider
本身只是一個容器,其內(nèi)部持有的 Transport 類才是能提供跨進(jìn)程調(diào)用的支持铺浇。
Transport
類繼承自 ContentProviderNative
類痢畜,作為ContentProvider
的 Binder
通信服務(wù)端 BBinder
。
ContentProviderNative
中定義的 ContentProviderProxy
類將作為 Binder
通信的服務(wù)端代理,為客戶端提供交互
在上面的代碼中丁稀,ActivityThread
用 mLocalProviders
保存運行在本地的 ContentProvider
吼拥,使用的鍵值的key為 ContentProvider的Binder
通信服務(wù)端。
####### Step 3.1.2.1.1 publishContentProviders
ContentProvider
初始化完成后线衫,我們需要向 AMS
注冊它凿可。
com.android.app.ActivityThread
private void installContentProviders(
...
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
...
}
這段代碼是注冊ContentProvider的通用代碼.
因此即使我們現(xiàn)在的流程運行在AMS中,此處仍然將通過Binder通信進(jìn)行調(diào)用授账。
com.android.server.app.ActivityManagerService
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (providers == null) {
return;
}
enforceNotIsolatedCaller("publishContentProviders");
synchronized (this) {
//找到調(diào)用者對應(yīng)的ProcessRecord對象
final ProcessRecord r = getRecordForAppLocked(caller);
...
final long origId = Binder.clearCallingIdentity();
final int N = providers.size();
for (int i = 0; i < N; i++) {
// ProcessRecord的pubProviders中保存了ContentProviderRecord信息
// 這是根據(jù)PMS解析出的Package信息生成的
// 此處主要發(fā)布的ContentProvider枯跑,必須是該Packager已經(jīng)聲明的
ContentProviderHolder src = providers.get(i);
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
...
if (dst != null) {
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
// 按名稱保存到MProviderMap
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
// 按 authority保存到mProviderMap
mProviderMap.putProviderByName(names[j], dst);
}
// mLaunchingProviders 保存處于啟動狀態(tài)的Provider
int launchingCount = mLaunchingProviders.size();
int j;
boolean wasInLaunchingProviders = false;
for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
// 啟動完成后,從列表中移除
mLaunchingProviders.remove(j);
wasInLaunchingProviders = true;
j--;
launchingCount--;
}
}
if (wasInLaunchingProviders) {
// 取消啟動超時的消息
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
// 通知
dst.notifyAll();
}
// 沒發(fā)布一個ContentProvider白热,均調(diào)整對應(yīng)進(jìn)程的oom_adj
updateOomAdjLocked(r, true);
// 判斷敛助,并在需要的時候更新ContentProvider相關(guān)的統(tǒng)計信息
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
}
}
Binder.restoreCallingIdentity(origId);
}
}
publishContentProvider
函數(shù)結(jié)束后,一個 ContentProvider
就算正式在系統(tǒng)中注冊了棘捣。
在 AMS
的啟動過程中辜腺,此處注冊的是 SettingProvider
此后,Setting數(shù)據(jù)庫相關(guān)的操作均由它來管理乍恐。
注意到上面的 ContentProvider
注冊到 AMS
后评疗,進(jìn)行了notifyAll
的操作。
舉例來說:進(jìn)程需要查詢一個數(shù)據(jù)庫茵烈,需要通過進(jìn)程B中的某個 ContentProvider
來實施百匆。如果 B 還未啟動,那么 AMS
就需要先啟動 B呜投。在這段時間內(nèi)加匈,A需要等待B注冊啟動對應(yīng)的 ContentProvider
。B一旦完成 ContentProvider
的注冊仑荐,就需要告知A退出等待繼續(xù)后續(xù)的查詢工作雕拼。
Step SystemServer # systemReady
接下來,我們看看AMS啟動的最后一部分:systemReady
com.android.server.SystemServer
private void startOtherServices() {
...
// Step 3.1
mActivityManagerService.installSystemProviders();
...
mPackageManagerService.systemReady();
...
// Step 3.2
mActivityManagerService.systemReady(new Runnable() {
...
});
}
在SystemServer中的startOtherServices的最后調(diào)用了AMS的systemReady函數(shù)
可以看到第一個參數(shù)為Runnable粘招。
由于此處代碼量很大啥寇,所以先分段查看 AMS
中systemReady
的處理流程,然后再查看 Runnable
中的處理流程洒扎。
Step 3.2.1 階段一
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
traceLog.traceBegin("PhaseActivityManagerReady");
synchronized(this) {
// 第一次mSystemReady=false
if (mSystemReady) {
// If we're done calling all the receivers, run the next "boot phase" passed in
// by the SystemServer
if (goingCallback != null) {
goingCallback.run();
}
return;
}
// 這一部分主要是調(diào)用一些關(guān)鍵服務(wù)systemReady相關(guān)的函數(shù)
mLocalDeviceIdleController
= LocalServices.getService(DeviceIdleController.LocalService.class);
mAssistUtils = new AssistUtils(mContext);
mVrController.onSystemReady();
// Make sure we have the current profile info, since it is needed for security checks.
mUserController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mAppOpsService.systemReady();
// 系統(tǒng)準(zhǔn)備完畢
mSystemReady = true;
}
try {
sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
.getSerial();
} catch (RemoteException e) {}
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
// mPidsSelfLocked中保存當(dāng)前正在運行的所有進(jìn)程的信息
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
// isAllowedWhileBooting中判斷FLAG_PERSISTENT標(biāo)志
// 在AMS啟動完成前辑甜,如果沒有 FLAG_PERSISTENT 標(biāo)志的進(jìn)程已經(jīng)啟動了,將其加入到procsToKill列表中
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
synchronized(this) {
if (procsToKill != null) {
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
// 關(guān)閉 procsToKill中的進(jìn)程
removeProcessLocked(proc, true, false, "system update done");
}
}
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
// 進(jìn)程準(zhǔn)備完畢
mProcessesReady = true;
}
...
// 根據(jù)數(shù)據(jù)庫和資源文件袍冷,獲取一些配置參數(shù)
retrieveSettings();
final int currentUserId;
synchronized (this) {
// 得到當(dāng)前的用戶Id
currentUserId = mUserController.getCurrentUserIdLocked();
// 讀取 urigrant.xml磷醋,為其中定義的 ContentProvider 配置對指定Uri數(shù)據(jù)的訪問/修改權(quán)限
// 原生的代碼中,似乎沒有 urigrants.xmls
// 實際使用的 grant-uri-permission 是分布式定義的
readGrantedUriPermissionsLocked();
}
if (goingCallback != null) goingCallback.run();
traceLog.traceBegin("ActivityManagerStartApps");
...
}
這部分的主要工作:
這一部分的工作主要是
- 調(diào)用一些關(guān)鍵服務(wù)的初始化函數(shù)
- 殺死那些沒有 FLAG_PERSISTENT 卻在AMS啟動完成前已經(jīng)存在的進(jìn)程
- 獲取一些配置參數(shù)胡诗。
只有Java進(jìn)程才會向AMS注冊邓线,而一般的Native進(jìn)程不會向AMS注冊淌友,因此這里殺死的進(jìn)程時Java進(jìn)程
Step 3.2.2 階段二
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
// 調(diào)用參數(shù)傳入的 Runnable對象,SystemServer中有具體的定義
// Step 3.2.2.1
if (goingCallback != null) goingCallback.run();
traceLog.traceBegin("ActivityManagerStartApps");
...
// 內(nèi)部循環(huán)遍歷所有的系統(tǒng)服務(wù)的onStartUser接口
mSystemServiceManager.startUser(currentUserId);
synchronized (this) {
// Only start up encryption-aware persistent apps; once user is
// unlocked we'll come back around and start unaware apps
// 啟動persistent為1的Application所在的進(jìn)程
// Step 3.2.2.2
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
// Start up initial activity.
mBooting = true;
// Enable home activity for system user, so that the system can always boot. We don't
// do this when the system user is not setup since the setup wizard should be the one
// to handle home activity in this case.
// 當(dāng)isSplitSystemUser返回true時褂痰,意味著system user和primary user是分離的
// 這里應(yīng)該是讓system user也有啟動 home activity 的權(quán)限吧
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
// Step 3.2.2.3 啟動 Home
startHomeActivityLocked(currentUserId, "systemReady");
try {
// 發(fā)送消息亩进,觸發(fā)處理Uid錯誤的Application
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
...
mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
}
} catch (RemoteException e) {
}
// 發(fā)送一些廣播信息
...
// 這里暫不深入症虑,屬于Activity的啟動過程缩歪,onResume
mStackSupervisor.resumeFocusedStackTopActivityLocked();
...
}
}
這部分代碼的主要工作:
- 通知所有的系統(tǒng)服務(wù)執(zhí)行onStartUser()
- 啟動persistent=1的Application所在的進(jìn)程
- 啟動Home
- 執(zhí)行Activity的onResume
Step 3.2.2.1 SystemServer.systemReady的Runnable回調(diào)函數(shù)
回調(diào)函數(shù)定義在 ServerServer#startOtherServices 中雁社,其中會調(diào)用大量服務(wù)的 onBootPhase
函數(shù)绊含、一些對象的systemReady
函數(shù)或 systemRunning
函數(shù)泽台。
com.android.server.SystemServer
mActivityManagerService.systemReady(() -> {
// 遍歷系統(tǒng)服務(wù)startBootPhase啟動階段代碼
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
try {
// AMS 啟動 NativeCrashListener皱蹦,監(jiān)聽“/data/system/ndebugsocket”中的信息
// 實際上就是監(jiān)聽 debuggerd(調(diào)試工具) 傳入的信息
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
// No dependency on Webview preparation in system server. But this should
// be completed before allowring 3rd party
final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
Future<?> webviewPrep = null;
if (!mOnlyCore) {
webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
Slog.i(TAG, WEBVIEW_PREPARATION);
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(WEBVIEW_PREPARATION);
ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
mZygotePreload = null;
mWebViewUpdateService.prepareWebViewInSystemServer();
traceLog.traceEnd();
}, WEBVIEW_PREPARATION);
}
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
traceBeginAndSlog("StartCarServiceHelperService");
mSystemServiceManager.startService(CarServiceHelperService.class);
traceEnd();
}
// 啟動 SystemUi
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
// 一系列 systemReady
try {
if (networkScoreF != null) networkScoreF.systemReady();
} catch (Throwable e) {
reportWtf("making Network Score Service ready", e);
}
...
...
// 啟動Watchdog
Watchdog.getInstance().start();
// Wait for all packages to be prepared
mPackageManagerService.waitForAppDataPrepared();
// confirm webview completion before starting 3rd party
if (webviewPrep != null) {
ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
}
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
// 一系列 systemRunning
try {
if (locationF != null) locationF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying Location Service running", e);
}
...
...
}, BOOT_TIMINGS_TRACE_LOG);
Step 3.2.2.2 AMS # startPersistentApps
啟動 persistent 標(biāo)志的進(jìn)程
com.android.server.am.ActivityManagerService
private void startPersistentApps(int matchFlags) {
...
synchronized (this) {
try {
//從PMS中得到persistent為1的ApplicationInfo
final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
//由于framework-res.apk已經(jīng)由系統(tǒng)啟動雄右,所以此處不再啟動它
if (!"android".equals(app.packageName)) {
// addAppLocked中將啟動application所在進(jìn)程
addAppLocked(app, false, null /* ABI override */);
}
}
} catch (RemoteException ex) {
}
}
}
跟進(jìn)一下 addAppLocked 函數(shù)
com.android.server.am.ActivityManagerService
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
String abiOverride) {
//以下是取出或構(gòu)造出ApplicationInfo對應(yīng)的ProcessRecord
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(info.processName, info.uid, true);
} else {
app = null;
}
if (app == null) {
app = newProcessRecordLocked(info, null, isolated, 0);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
...
// This package really, really can not be stopped.
try {
//通過PKMS將package對應(yīng)數(shù)據(jù)結(jié)構(gòu)的StoppedState置為fasle
AppGlobals.getPackageManager().setPackageStoppedState(
info.packageName, false, UserHandle.getUserId(app.uid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
}
if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
app.persistent = true;
app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
//啟動應(yīng)用所在進(jìn)程粟害,將發(fā)送消息給zygote柿祈,后者fork出進(jìn)程
startProcessLocked(app, "added application", app.processName, abiOverride,
null /* entryPoint */, null /* entryPointArgs */);
}
return app;
}
這里最終通過 startProcessLocked
函數(shù)屯远,啟動實際的應(yīng)用進(jìn)程苫昌。
Zygote
進(jìn)程中的 server socket
將接受消息颤绕,然后為應(yīng)用fork出進(jìn)程
Step 3.2.2.3 AMS # startHomeActivityLocked
啟動Home Activity
com.android.server.am.ActivityManagerService
boolean startHomeActivityLocked(int userId, String reason) {
...
Intent intent = getHomeIntent();
//根據(jù)intent中攜帶的ComponentName,利用PMS得到ActivityInfo
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
//此時home對應(yīng)進(jìn)程應(yīng)該還沒啟動祟身,app為null
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
//啟動home
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
...
}
return true;
}
這里暫時不深究Home Activity啟動的具體過程奥务。當(dāng)啟動成功后,會調(diào)用Activity#handleResumeActivity方法袜硫,最終調(diào)用到 ActivityStackSupervisor#activityIdleInternalLocked氯葬。
com.android.server.am.ActivityStackSupervisor
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
...
if (isFocusedStack(r.task.stack) || fromTimeout) {
booting = checkFinishBootingLocked();
}
...
}
跟進(jìn)一下 checkFinishBootingLocked
函數(shù)
com.android.server.am.ActivityStackSupervisor
private boolean checkFinishBootingLocked() {
//mService為AMS,mBooting變量在AMS回調(diào)SystemServer中定義的Runnable時婉陷,置為了true
final boolean booting = mService.mBooting;
boolean enableScreen = false;
mService.mBooting = false;
if (!mService.mBooted) {
mService.mBooted = true;
enableScreen = true;
}
if (booting || enableScreen) {帚称、
//調(diào)用AMS的接口,發(fā)送消息
mService.postFinishBooting(booting, enableScreen);
}
return booting;
}
最終秽澳,AMS
的 finishBooting
函數(shù)將被調(diào)用:
com.android.server.am.ActivityManagerService
final void finishBooting() {
...
//以下是注冊廣播接收器闯睹,用于處理需要重啟的package
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
pkgFilter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
if (pkgs != null) {
for (String pkg : pkgs) {
synchronized (ActivityManagerService.this) {
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
0, "query restart")) {
setResultCode(Activity.RESULT_OK);
return;
}
}
}
}
}
}, pkgFilter);
...
// Let system services know.
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
//以下是啟動那些等待啟動的進(jìn)程
synchronized (this) {
// Ensure that any processes we had put on hold are now started
// up.
final int NP = mProcessesOnHold.size();
if (NP > 0) {
ArrayList<ProcessRecord> procs =
new ArrayList<ProcessRecord>(mProcessesOnHold);
for (int ip=0; ip<NP; ip++) {
...
startProcessLocked(procs.get(ip), "on-hold", null);
}
}
}
}
...
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
// Start looking for apps that are abusing wake locks.
//每5min檢查一次系統(tǒng)各應(yīng)用進(jìn)程使用電量的情況,如果某個進(jìn)程使用WakeLock的時間過長
//AMS將關(guān)閉該進(jìn)程
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1");
...
//此處從代碼來看發(fā)送的是ACTION_LOCKED_BOOT_COMPLETED廣播
//在進(jìn)行unlock相關(guān)的工作后担神,mUserController將調(diào)用finishUserUnlocking楼吃,發(fā)送SYSTEM_USER_UNLOCK_MSG消息給AMS
//AMS收到消息后,調(diào)用mUserController的finishUserUnlocked函數(shù)杏瞻,經(jīng)過相應(yīng)的處理后所刀,
//在mUserController的finishUserUnlockedCompleted中,最終將會發(fā)送ACTION_BOOT_COMPLETED廣播
mUserController.sendBootCompletedLocked(...);
...
}
}
最終AMS啟動 HomeActivity 結(jié)束捞挥,并發(fā)送 ACTION_BOOT_COMPLETED 廣播時浮创,AMS的啟動過程告一段落。
總結(jié)
對于整個AMS
啟動過程來說砌函,本文涉及的內(nèi)容只是其中極小一部分斩披。
整個過程溜族,可以將AMS的啟動過程分為四步
創(chuàng)建出 SystemServer 進(jìn)程的 Android 運行環(huán)境
這個流程,創(chuàng)建SystemServer進(jìn)程對應(yīng)的ActivityThread和ContextImpl垦沉,構(gòu)成Android運行環(huán)境
AMS后續(xù)工作依賴SystemServer在此創(chuàng)建出的運行環(huán)境完成AMS的初始化和啟動
這個流程煌抒,調(diào)用了AMS的構(gòu)造函數(shù)和start函數(shù),完成AMS一些初始化工作將SystemServer進(jìn)程納入到AMS的管理體系
這個流程厕倍,AMS加載了SystemServer中framework-res.apk的信息寡壮,并啟動和注冊了SettingsProvider.apk。涉及了ContentProvider的安裝讹弯。AMS啟動完畢后才能進(jìn)行的工作
這個流程况既,AMS調(diào)用 systemReady函數(shù),通知系統(tǒng)的其他服務(wù)和進(jìn)程组民,可以進(jìn)行對應(yīng)的工作棒仍。
并且,Home Activity被啟動了臭胜,當(dāng)Home Activity被加載完成后莫其,最終會觸發(fā)ACTION_BOOT_COMPLETED廣播。
- 創(chuàng)建
system
進(jìn)程的運行環(huán)境耸三,一個ActivityThread
主線程乱陡,一個和系統(tǒng)進(jìn)程相關(guān)的Context
對象 - 調(diào)用
AMS
的構(gòu)造方法,對必要的內(nèi)容進(jìn)行初始化 - 將 AMS 注冊到
ServiceManager
中吕晌,同時對system
進(jìn)程創(chuàng)建一個ProcessRecord
對象蛋褥,并設(shè)置Context
的application
為framework-res
的application
對象。由于AMS
是Android
世界的進(jìn)程管理和調(diào)度中心睛驳,盡管system
貴為系統(tǒng)進(jìn)程烙心,也要將其并入AMS
的管理范圍 - 為
system
進(jìn)程加載SettingProvider
- 調(diào)用
systemReady
方法做系統(tǒng)啟動完畢前的最后一些掃尾工作。最HomeActivity
將呈現(xiàn)在用戶面前