AMS作為Android FrameWork中最核心的一個(gè)部分,是應(yīng)用層開發(fā)者進(jìn)階的里程碑,本文是AMS專欄的第一篇文章,介紹AMS的啟動(dòng)相關(guān):
在學(xué)習(xí)AMS之前破加,需要掌握一些基礎(chǔ)知識(shí):
在學(xué)習(xí)完上面的內(nèi)容后,我們可以知道AMS的啟動(dòng)是由SystemServer進(jìn)程發(fā)起的:
AMS的入口方法SystemServer的main()做了兩件事:
- 調(diào)用
CreateSystemContext()
創(chuàng)建SystemContext - 開啟三類服務(wù):引導(dǎo)服務(wù)雹嗦,核心服務(wù)范舀,其他服務(wù)
1. SystemServer.createSystemContext():
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
}
ActivityThread.systemMain():
public static ActivityThread systemMain() {
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
在SystemMain中,首先創(chuàng)建了一個(gè)SystemServer進(jìn)程的ActivityThread了罪,沒錯(cuò)锭环,這就是用戶進(jìn)程的入口main的那個(gè)ActivityThread,所以從某種意義上講泊藕,我們也可以將SystemServer進(jìn)程看成一個(gè)App辅辩;
調(diào)用了ActivityThread的attach(),注意娃圆,這里傳入的是true
玫锋,而我們正常的App傳入的是false,這個(gè)字段表示是否是系統(tǒng)進(jìn)程(SystemServer進(jìn)程):
ActivityThread.attach():
private void attach(boolean system, long startSeq) {
...
if (!system) { // 如果是正常App進(jìn)程讼呢,傳入false
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
}
...
} else { // 如果是SystemServer進(jìn)程撩鹿,傳入true
...
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
}
}
}
如果是正常的APP,那么進(jìn)入if邏輯悦屏,調(diào)用AMS的代理發(fā)起一次Binder消息节沦,實(shí)際調(diào)用AMS的attachApplication();
在本次情況中是由SystemServer進(jìn)程發(fā)起的键思,進(jìn)入else邏輯:
- 調(diào)用ContextImpl.createAppContext()創(chuàng)建App Context
- 注意上一個(gè)方法,傳入了一個(gè)
getSystemContext().mPackageInfo
參數(shù) - 調(diào)用makeApplication創(chuàng)建Application
我們先來看傳入的參數(shù):
ActivityThread.getSystemContext()
public ContextImpl getSystemContext() {
synchronized (this) {
mSystemContext = ContextImpl.createSystemContext(this);
}
getSystemContext()調(diào)用了ContextImpl的createSystemContext():
ContextImpl.createSystemContext():
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
ContextImpl有一系列的創(chuàng)建Context的static 方法:
在這里創(chuàng)建了SystemContext甫贯,Context的具體作用就是用來獲取資源吼鳞,比如你的Activity需要使用apk里面的資源,而系統(tǒng)SystemServer也需要使用系統(tǒng)預(yù)設(shè)的資源文件叫搁,所以在這里也創(chuàng)建了一個(gè)Context對(duì)象;
那么Context是如何獲取資源的呢赔桌?答案是LoadedApk
這個(gè)類,LoadedApk是apk文件在內(nèi)存中的存在形式
所以一般ApplicationContext或者ActivityContext都會(huì)持有它對(duì)應(yīng)的apk文件的內(nèi)存形式LoadedApk對(duì)象常熙;那么我們的SystemServer是跟哪個(gè)APK綁定呢纬乍??裸卫?看下面這張圖就明白了:
雖然它是一個(gè)LoadedAPK對(duì)象,但是并沒有對(duì)應(yīng)apk文件纽竣,它存在的意義就是為SystemContext服務(wù)墓贿,為它提供獲取系統(tǒng)資源的能力;注意倒數(shù)第二第三行蜓氨,SystemClassLoader聋袋,SystemResource,如果是通過其他構(gòu)造方法創(chuàng)建的LoadedApk穴吹,就不會(huì)有這個(gè)值幽勒,他們是通過對(duì)應(yīng)apk文件解析出來的數(shù)據(jù);
至此港令,我們的SystemContext創(chuàng)建完畢啥容,回到ActivityThread.attach():這一步,參數(shù)看好了顷霹,參數(shù)就是SystemContext的LoadedApk咪惠,就是那個(gè)沒有apk的LoadedAPK;
ContextImpl.CreateAppContext:
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;
}
在這里因?yàn)閭魅氲腖oadedAPK是被閹割的LoadedAPK對(duì)象淋淀,所以這個(gè)ApplicationContext遥昧,本質(zhì)上和SystemContext一樣,他們的resource都是System Resource朵纷;
context.mPackageInfo.makeApplication(true, null):
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
}
...
return app;
}
mInstrumentation.newApplication()
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
makeApplication的邏輯就是創(chuàng)建Application對(duì)象炭臭,然后調(diào)用Application的attach方法:
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
保存Application Context 和 LoadedApk到Application
至此SystemServer創(chuàng)建System Context的操作分析完畢,下面分析SystemServer的run()中開啟三類服務(wù)中關(guān)于AMS的邏輯
SystemServer.startBootstrapServices():
private void startBootstrapServices() {
...
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setInstaller(installer);
mActivityManagerService.initPowerManagement();
mActivityManagerService.setSystemProcess();
}
在啟動(dòng)引導(dǎo)服務(wù)startBootstrapServices
這個(gè)方法中袍辞,涉及AMS的邏輯主要做了四件事:
- 創(chuàng)建AMS實(shí)例
- 設(shè)置installer鞋仍,App安裝器
- 初始化PMS
- 調(diào)用setSystemProcess()
1. startService(ActivityManagerService.Lifecycle.class).getService();
startService()傳入了一個(gè)AMS的內(nèi)部類Lifecycle的Class對(duì)象,會(huì)創(chuàng)建一個(gè)Lifecycle的實(shí)例革屠,接著這個(gè)Lifecycle會(huì)調(diào)用自己的getService方法獲取AMS實(shí)例:
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
public ActivityManagerService getService() {
return mService;
}
下面看一下AMS的構(gòu)造方法凿试,AMS的構(gòu)造方法中排宰,做了很多事情:
public ActivityManagerService(Context systemContext) {
...
// 前臺(tái)服務(wù)線程
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
// 后臺(tái)服務(wù)線程
sKillThread = new ServiceThread(TAG + ":kill",
THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
// CPU線程
mProcessCpuThread = new Thread("CpuTracker") ;
// AMS家族:
mConstants = new ActivityManagerConstants(this, mHandler);
mServices = new ActiveServices(this);
mStackSupervisor = createStackSupervisor();
mActivityStartController = new ActivityStartController(this);
// 開啟 watch dog
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
// 創(chuàng)建 AppOpsService 那婉, Android原生應(yīng)用程序權(quán)限管理相關(guān)
mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
//創(chuàng)建進(jìn)程狀態(tài)服務(wù)板甘,監(jiān)聽進(jìn)程轉(zhuǎn)發(fā)服務(wù)
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
//創(chuàng)建電量狀態(tài)服務(wù)
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
}
在AMS的構(gòu)造方法中,大概做了以下幾件事:
- 創(chuàng)建各個(gè)工作線程详炬,前臺(tái)服務(wù)線程盐类,后臺(tái)服務(wù)線程,CPU線程
- 實(shí)例化AMS家族成員呛谜,ActivityManagerConstants在跳,ActiveServices,StackSupervisor隐岛,ActivityStartController猫妙,這些在后續(xù)會(huì)詳細(xì)介紹;
- 開啟各種服務(wù)聚凹,watch dog割坠,Appops,ProcessStatsService妒牙,BatteryStatsService
- 軟件看門狗來監(jiān)控SystemServer中的線程彼哼。一旦發(fā)現(xiàn)問題,WatchDog會(huì)殺死SystemServer進(jìn)程湘今。SystemServer的父進(jìn)程Zygote接收到SystemServer的死亡信號(hào)后敢朱,會(huì)殺死自己。Zygote進(jìn)程死亡的信號(hào)傳遞到Init進(jìn)程后摩瞎,Init進(jìn)程會(huì)殺死Zygote進(jìn)程所有的子進(jìn)程并重啟Zygote拴签。這樣整個(gè)手機(jī)相當(dāng)于重啟一遍。通常SystemServer出現(xiàn)問題和kernel并沒有關(guān)系愉豺,所以這種“軟重啟”大部分時(shí)候都能夠解決問題篓吁。而且這種“軟重啟”的速度更快,對(duì)用戶的影響也更小蚪拦。
至此杖剪,第一步AMS的實(shí)例化分析完畢,步驟2 和 步驟3 是設(shè)置APk安裝器和初始化PMS驰贷,不做過多介紹盛嘿,下面詳細(xì)看下步驟4setSystemProcess()
4 mActivityManagerService.setSystemProcess();
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_HIGH);
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this),
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
}
}
// Start watching app ops after we and the package manager are up and running.
mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null);
}
在AMS的setSystemProcess()中主要做了四件事:
- 添加各種服務(wù)到ServiceManager中:this(自己AMS服務(wù)),內(nèi)存括袒,圖像次兆,權(quán)限,cpu锹锰,進(jìn)程芥炭,相關(guān)服務(wù)
- installSystemApplicationInfo
- 創(chuàng)建ProcessRecord對(duì)象
- 調(diào)用AppOps服務(wù)的startWatch方法開啟對(duì)應(yīng)用程序包給定權(quán)限的監(jiān)聽漓库;
步驟2:installSystemApplicationInfo():
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader);
getSystemUiContext().installSystemApplicationInfo(info, classLoader);
// give ourselves a default profiler
mProfiler = new Profiler();
}
}
步驟2做了兩件事:
- 將ApplicationInfo對(duì)象設(shè)置給SystemContext
- 創(chuàng)建Profiler對(duì)象,用于性能統(tǒng)計(jì)
至此SystemService開啟引導(dǎo)服務(wù)中AMS相關(guān)的邏輯分析完畢园蝠;
SystemServer.startOtherServices():
mActivityManagerService.systemReady(() -> {
mSystemServiceManager.startBootPhase(
try {
mActivityManagerService.startObservingNativeCrashes();
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
mVrController.onSystemReady();
mUserController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mAppOpsService.systemReady();
mSystemReady = true;
startHomeActivityLocked(currentUserId, "systemReady");
}
在startOtherServices()中渺蒿,AMS的主要邏輯就是調(diào)用了SystemReady()開啟一個(gè)Activity,開啟Activity的內(nèi)容后期再講彪薛,會(huì)設(shè)計(jì)AMS的大家族茂装;