? ActivityManagerService服務是Android系統(tǒng)核心服務,負責Android管理系統(tǒng)Activity,Service,ContentProvider和BroadcastReceiver 四大組件,同時還負責Android系統(tǒng)中的進程管理。由此可見ActivityManagerService服務對于Android系統(tǒng)來講非常重要,我們就從以下幾個方面來了解下AMS服務。
- AMS服務的啟動和初始化過程
- AMS如何啟動和管理Activity
- AMS如何啟動和管理Service
- AMS如何管理BroadCastReceiver
- AMS如何管理ContentProvider
此篇文章就來總結下Ams服務的啟動和初始化過程。
ActivityManagerService的啟動和初始化過程
系統(tǒng)進程運行環(huán)境的初始化
在分析AMS服務之前我們先來了解下什么是Context.
Context是什么?
Context是一個抽象類,其通用實現(xiàn)在ContextImpl類中。是一個訪問application環(huán)境全局信息的接口,通過它可以訪問application的資源和相關的類,其主要功能如下:
? 啟動Activity
? 啟動和停止Service
? 發(fā)送廣播消息(Intent)
? 注冊廣播消息(Intent)接收者
? 可以訪問APK中各種資源(如Resources和AssetManager等)
? 可以訪問Package的相關信息
? APK的各種權限管理
對你的應用程序而言,Context就是一個無所不知的大管家,大家需要什么,直接問它就可以了。

Context的類關系圖可知,ContextImpl最終實現(xiàn)了Context相關方法,ContextWrapper只是一個代理類,Activity,Service,Application都是實現(xiàn)了ContextWrapper,所以在Activity,Service和Application中調(diào)用的context的相關方法,最終都有ContextImpl來實現(xiàn)。而ContextImpl最終是應用程序的大管家,管理著操作本應用的相關方法。
?Android系統(tǒng)中的進程分為兩種,應用進程和系統(tǒng)進程。而ActivityThread就是應用進程的主線程,Android系統(tǒng)的應用進程啟動后首先運行ActivityThread的main函數(shù),ActivityThread和AMS進行通信,調(diào)度和執(zhí)行應用進程的四大組件。
?SystemServer是Android的系統(tǒng)進程,由于系統(tǒng)進程中也有一些Activity和系統(tǒng)資源,為了保證調(diào)用方式統(tǒng)一,系統(tǒng)進程也需要ActivityThread和Context等Android運行環(huán)境。所以SystemServer也是一個特殊的應用進行。
對Android而言系統(tǒng)進程而言,SysrtemServer也是一個特別的應用程序,也有自己的Context上下文環(huán)境,而系統(tǒng)的Context又是怎么創(chuàng)建的呢?
它是SystemServer啟動之后,在createSystemContext方法中創(chuàng)建的。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
……
}
第一步ActivityThread.systemMain方法,該方法生成了一個ActivityThread對象。
public static ActivityThread systemMain() {
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
首先創(chuàng)建了一個ActivityThread對象,然后調(diào)用attach方法。
ActivityThread的構造方法很簡單就是創(chuàng)建了一個ResourcesManager對象,用于管理應用程序中的資源文件
那就接著看ActivityThread的Attach方法。
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
……
}else{
//修改系統(tǒng)進程的名稱為system_process
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
//創(chuàng)建一個該進程相關的context對象
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
}
?attach方法傳進來的參數(shù)為true,代表該進程為系統(tǒng)進程,所以直接看else中的方法實現(xiàn)。
?首先調(diào)用setAppName將系統(tǒng)應用的名稱改為system_process,調(diào)試的時候我們可以看到系統(tǒng)的進程名稱為system_process.
?然后創(chuàng)建了一個Instrumentation類,該類是一個工具類,ActivityThread接收到AMS的指令創(chuàng)建和調(diào)度交互都由它來執(zhí)行。
?然后調(diào)用createAppContext來創(chuàng)建一個系統(tǒng)的ContextImpl的大管家,傳入的關鍵參數(shù)為系統(tǒng)進程的apk相關信息。后面再分析getSystemContext方法,然后創(chuàng)建了一個android,app.application,并調(diào)用了它的onCreate方法。
getSystemContext方法
systemContext最終由ContextImpl.createSystemContext方法來創(chuàng)建。
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread,
packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetricsLocked());
return context;
}
首先創(chuàng)建了一個LoadedApk對象,然后根據(jù)LoadedApk對象創(chuàng)建了一個ContextImpl對象。
LoadedApk代表一個加載到系統(tǒng)中的APK。 其中保存了apk的基本信息
LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.packageName = "android";
mPackageName = "android";
mAppDir = null;
mResDir = null;
mSplitAppDirs = null;
mSplitResDirs = null;
mOverlayDirs = null;
mSharedLibraries = null;
mDataDir = null;
mDataDirFile = null;
mLibDir = null;
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
mRegisterPackage = false;
mClassLoader = ClassLoader.getSystemClassLoader();
mResources = Resources.getSystem();
}
LoadedAPK的這個構造方法只有系統(tǒng)進程創(chuàng)建的時候可以調(diào)用。它代表一個系統(tǒng)進程的apk,它里面存儲著資源文件的位置,jni包的位置等信息,包名為android。其實代表的就是就是framework-res.apk。該apk僅供systemServer使用。
private ContextImpl(ContextImpl container, ActivityThread mainThread,
LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
Display display, Configuration overrideConfiguration, int createDisplayWithId) {
mOuterContext = this;
//framework-res.apk的主進程為當前的ActivityThread
mMainThread = mainThread;
mActivityToken = activityToken;
mRestricted = restricted;
if (user == null) {
user = Process.myUserHandle();
}
mUser = user;
//packageinfo的信息
mPackageInfo = packageInfo;
//初始化資源管理器
mResourcesManager = ResourcesManager.getInstance();
……
ResourcesManager.getInstance().getAdjustedDisplay(displayId, mDisplayAdjustments);
Resources resources = packageInfo.getResources(mainThread);
if (resources != null) {
if (displayId != Display.DEFAULT_DISPLAY
|| overrideConfiguration != null
|| (compatInfo != null && compatInfo.applicationScale
!= resources.getCompatibilityInfo().applicationScale)) {
resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
overrideConfiguration, compatInfo);
}
}
mResources = resources;
……
//初始化系統(tǒng)的contentResolver
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
}
?調(diào)用ContextImpl的構造方法生成了一個ContextImpl。該構造方法主要就是初始化了ContextImpl中的一些信息,如ResourManager等。同時將剛才創(chuàng)建的LoadAPK的package信息保存到的Context中,最終生成了一個和系統(tǒng)進程相關的Context。因為它保存了系統(tǒng)相關的信息
?調(diào)用systemMain函數(shù)結束后,首先生成了一個ActivityThread對象,它代表應用進程的主線程。得到一個Context對象,它背后所指向的Application環(huán)境與framework-res.apk有關。
?這兩樣東西就構成了Android程序的運行環(huán)境。我們自己寫的apk的代碼最終在ActivityThread線程上運行,通過Context應用程序的大管家,可以調(diào)用進程所用到的資源和方法。
?為什么要為系統(tǒng)進程設置應用的運行環(huán)境呢,因為系統(tǒng)進程中包含了一個framewrok-res.apk的應用進程,這個apk也需要一個運行環(huán)境。
?在SystemServer進程中也創(chuàng)建了一個Android運行環(huán)境,說明SystemServer系統(tǒng)進程也被看做一個特殊的應用程序。因為系統(tǒng)進程中也會有Activity界面和資源,所以也為他創(chuàng)建了一個運行環(huán)境,這樣做它就可以和普通應用進程一樣使用統(tǒng)一的接口和系統(tǒng)交互了。
了解了系統(tǒng)Context的創(chuàng)建步驟及系統(tǒng)運行環(huán)境的概念,我們就一步一步的來分析AMS啟動和初始化的過程,首先分析啟動AMS服務。
AMS服務的啟動過程和其他系統(tǒng)服務的啟動過程一樣,也是在SystemServer服務中啟動起來的。首先來看SystemServer中關于ActivityManagerService的一些相關的方法。
AMS服務的啟動過程
private void startBootstrapServices() {
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemProcess();
……
mActivityManagerService.installSystemProviders();
……
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
上面的的幾個方法就是SystemServer中關于AMS啟動時的幾個關鍵方法,主要分為4個步驟
1:創(chuàng)建AMS對象,并啟動服務
2:將AMS所在的系統(tǒng)進程,添加到進程管理中去
3:為系統(tǒng)進程安裝ContentProvider對象
4:在systemReady方法中做善后操作
一個一個的來看先這些方法的作用,這些方法就是AMS的啟動和初始化過程。
啟動ActivityManagerService的方法
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
AMS服務同樣是通過SystemServiceManager來啟動的。那我們首先來看ActivityManagerService.Lifecycle的構造方法,然后在來看它的Start函數(shù)。
Lifecycle的構造方法中很簡單就是構造一個AMS的對象
mService = new ActivityManagerService(context);
創(chuàng)建AMS對象的時候需要傳遞一個Context作為參數(shù),那這個mSystemContext是就是上面創(chuàng)建的系統(tǒng)Context。
接著看AMS的構造方法。
public ActivityManagerService(Context systemContext) {
//系統(tǒng)的context
mContext = systemContext;
//獲得系統(tǒng)的ActivityThread
mSystemThread = ActivityThread.currentActivityThread();
//創(chuàng)建一個HandlerThread用來處理AMS接收的命令
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = new UiHandler();
//初始化廣播的隊列
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;
//初始化Service相關的容器
mServices = new ActiveServices(this);
//初始化Provider相關的Map,里面保存了注冊的ContentProvider
mProviderMap = new ProviderMap(this);
//初始化并創(chuàng)建data/system/目錄
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
//初始化電量統(tǒng)計服務相關的信息
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.scheduleWriteToDisk();
mOnBattery = DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
mBatteryStatsService.getActiveStatistics().setCallback(this);
//初始化系統(tǒng)統(tǒng)計服務,用于統(tǒng)計系統(tǒng)的運行信息
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
//創(chuàng)建系統(tǒng)的第一個user,userID為0,該用戶具有管理員權限
mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
mUserLru.add(UserHandle.USER_OWNER);
updateStartedUserArrayLocked();
//獲取opengle的版本
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
//初始化字體語言等配置信息
mConfiguration.setToDefaults();
mConfiguration.setLocale(Locale.getDefault());
……;
mRecentTasks = new RecentTasks(this);
//初始化StackSupervisor,該類是Activity啟動和調(diào)度的核心類
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
從代碼中可以看出,AMS的構造方法主要是在做一些初始化的先關操作。先保存了自己的運行環(huán)境的Context和ActivityThread。AMS負責調(diào)度四大組件,所以會初始化broadcast,service和contentProvider相關的變量,接著初始化了電量統(tǒng)計服務,創(chuàng)建了系統(tǒng)的第一個用戶,初始化了基本的配置信息,還創(chuàng)建了Activity調(diào)度的核心類,因為Activity調(diào)度比較復雜,Activity相關的信息初始化會在ActivityStackSupervisor中。
AMS的start方法。
private void start() {
mProcessCpuThread.start();
mBatteryStatsService.publish(mContext);
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
AMS的start方法很簡單,只是啟動了幾個服務,并把AMS服務自己保存到localService中供程序內(nèi)部調(diào)用。
AMS的構造方法和start方法中做了AMS服務一些變量的初始化和相關服務的初始化。接著看下一個重要的方法setSystemProcess
ActivityManagerService的setSystemProcess方法
public void setSystemProcess() {
try {
//將AMS注冊到ServiceManager中
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
//注冊其他服務到ServiceMananger中
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
//注冊權限服務到ServiceMananger中
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
//從PMS中查詢包名為android的application,即framework-res的Application信息
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
//將application信息配置到開始創(chuàng)建的activityThread中
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
//創(chuàng)建了一個ProcessRecord對象,該對象中保存著系統(tǒng)ongoing服務的進程信息
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) {
然后將系統(tǒng)進程的processRecord對象也添加到mPidsSelfLocked集合中,和普通應用的進程一樣,接收AMS的管理調(diào)度
mPidsSelfLocked.put(app.pid, app);
}
//更細進程管理的調(diào)度信息
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
?在setSystemProcess方法中,首先將自己AMS服務注冊到了ServiceManager中,然后又注冊了權限服務等其他的系統(tǒng)服務。通過先前創(chuàng)建的Context,得到PMS服務,檢索framework-res的Application信息,然后將它配置到系統(tǒng)的ActivityThread中。
為了能讓AMS同樣可以管理調(diào)度系統(tǒng)進程,也創(chuàng)建了一個關于系統(tǒng)進程的ProcessRecord對象,ProcessRecord對象保存一個進程的相關信息。然后將它保存到mPidsSelfLocked集合中方便管理。
?但是AMS具體是如何將檢索到的framework-res的application信息,配置到ActivityThread中的,需要繼續(xù)分析ActivityThread的installSystemApplicationInfo方法。
接著看installSystemApplicationInfo方法
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader);
}
}
這個方法中最終調(diào)用上面創(chuàng)建的SystemContext的installSystemApplication方法,那就接著看ConxtextImpl的installSystemApplication方法。
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
mPackageInfo.installSystemApplicationInfo(info, classLoader);
}
它有最終調(diào)用了mPackageInfo的installSystemApplication方法,mPackageInfo就是在創(chuàng)建Context對象的時候傳進來的LoadedApk,里面保存了一個應用程序的基本信息。
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
assert info.packageName.equals("android");
mApplicationInfo = info;
mClassLoader = classLoader;
}
?將framework-res.apk的application信息保存到了mApplication變量中。
?我們返回去看下第一次創(chuàng)建LoadedApk的時候,使用了一個參數(shù)的構造方法,該構造方法中mApplication變量是直接new了一個ApplicationInfo的對象,該applicationInfo并沒有指向任何一個應用,為什么開始的時候不直接指定,反而到現(xiàn)在再來重新做一次呢?
?這個是因為創(chuàng)建系統(tǒng)進程的context的時候AMS和PMS都還沒有起來,那時候沒有辦法指定它的application,現(xiàn)在AMS,PMS都起來之后再來賦值就可以了。
?setSystemProcess做了些什么工作呢?顧名思義,主要就是設置系統(tǒng)集成的一些信息,在這里設置了系統(tǒng)進程的Application信息,創(chuàng)建了系統(tǒng)進程的ProcessRecord對象將其保存在進程集合中,方便AMS管理調(diào)度。
ActivityManagerService的installSystemProvider方法
?Android系統(tǒng)中有很多配置信息都需要保存,這些信息是保存在SettingsProvider中,而這個SettingsProvider也是運行在SystemServer進程中的,由于SystemServer進程依賴SettingsProvider,放在一個進程中可以減少進程間通信的效率損失。
下面就來分析下如何將SettingsProvider.apk也加載到SystemServer進程中。
public final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (this) {
//找到名稱為”System”的進程,就是上一步創(chuàng)建的processRecord對象
ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
//找到所有和system進程相關的ContentProvider
providers = generateApplicationProvidersLocked(app);
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
//再次確認進程為system的provider,把不是該進程provider移除
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安裝到系統(tǒng)的ActivityThread中
mSystemThread.installSystemProviders(providers);
}
mCoreSettingsObserver = new CoreSettingsObserver(this);
}
找到名稱為system的進程對象,就是SystemServer進程,然后根據(jù)進程對象去查詢所有有關的ContentProvider,調(diào)用系統(tǒng)進程的主線程ActivityThread安裝所有相關的ContentProvider,
具體是如何查找相關的contentProvider和如何安裝ContentProvider到系統(tǒng)主線程的,接著分析下面兩個方法。
private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
List<ProviderInfo> providers = null;
try {
//調(diào)用PMS根據(jù)進程ID和進程名稱來查詢Provider
ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
queryContentProviders(app.processName, app.uid,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
providers = slice != null ? slice.getList() : null;
} catch (RemoteException ex) {
}
int userId = app.userId;
if (providers != null) {
int N = providers.size();
for (int i=0; i<N; i++) {
ProviderInfo cpi =
(ProviderInfo)providers.get(i);
……
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
//從AMS管理的contentProvider列表中查詢對應的provider
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
if (cpr == null) {
//如果AMS的Provider列表中沒有對應的Provider實例,就根據(jù)查詢的provider信息,創(chuàng)建一個對象保存到隊列中
cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
mProviderMap.putProviderByClass(comp, cpr);
}
//同時將provider保存到processRecord對象的pubProviders列表中
app.pubProviders.put(cpi.name, cpr);
……
}
}
return providers;
}
這個方法就是從PMS中查詢和SystemServer進程相關的Provider,也就是SettingsProvder,然后將它保存到AMS的contentProvider列表中,同時也將它保存到系統(tǒng)進程對象ProcessRecord的變量pubProviders列表中,保存到AMS的provider列表中是因為AMS需要管理所有的ContentProvder,保存到進程對象的pubProviders列表中是因為,每個ContentProvider都需要對應到一個進程中去。
接著看如何將SettingsProvider安裝到系統(tǒng)的主進程中去。
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
……
for (ProviderInfo cpi : providers) {
//通過installProvider方法把provider封裝成一個ContentProviderHolder對象,有利于進程間傳輸
IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
//將上面得到的contentProviderHolder對象發(fā)布到AMS服務,getApplicationThread代表本地進程的一個binder對象,binder對象可跨進程傳輸,它在AMS中對應一個ProcessRecord.
ActivityManagerNative.getDefault().publishContentProviders(
getApplicationThread(), results);
……
}
該方法將得到的contentProvider對象封裝成了contentProviderHolder對象,其實就是Binder對象,這樣就可以進程間傳輸了,然后跨進程調(diào)用AMS服務注冊Provider。AMS負責管理ContentProvider,只有將ContentProvider注冊到AMS服務其他進程才能訪問。
接著看AMS如何注冊Provider。
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
……
//根據(jù)調(diào)用者的進程得到相應的processRecord對象,就是系統(tǒng)進程的ProcessRecord
final ProcessRecord r = getRecordForAppLocked(caller);
……
final int N = providers.size();
for (int i = 0; i < N; i++) {
//ActivityThread客戶端傳過來的provider src
ContentProviderHolder src = providers.get(i);
//根據(jù)src provider name得到一開始保存的進程中保存的ProciderRecord
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);
}
……
}
AMS的注冊服務就是根據(jù)參數(shù)傳過來的provider信息,找到原先進程中pubProviders列表中保存的ContentProviderRecord,然后將它分別以類為key保存在mProviderMap中,和以authority為key保存在mProviderMap中。即AMS提供了多種方案來查找一個ContentProvider,一種是通過authority來查找,一種是指明CompomentName來查找。
此刻位置一個SettingsProvider就正式注冊到SystemServer進程中了,所以可以看出installSystemProvider方法的主要工作就是按照普通進程類似的方式,將SettingsProvider注冊到系統(tǒng)進程中,方便系統(tǒng)進程對settings的配置數(shù)據(jù)進行調(diào)用。
ActivityManagerService的systemReady方法
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
//初始化Doze模式的controller
mLocalDeviceIdleController
= LocalServices.getService(DeviceIdleController.LocalService.class);
//重置RecentTasks
mRecentTasks.clear();
mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
mTaskPersister.startPersisting();
……
//設置systemReady為true
mSystemReady = true;
}
ArrayList<ProcessRecord> procsToKill = null;
//收集那些在AMS之前啟動的進程
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
//將那些在AMS之前啟動的進程殺死,有的進程不能再AMS之前啟動
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);
removeProcessLocked(proc, true, false, "system update done");
}
}
}
//從settingsProvider的設置總初始化部分變量
retrieveSettings();
//調(diào)用callback方法,該方法在systemServer代碼中實現(xiàn)
if (goingCallback != null) goingCallback.run();
//查詢那些persistent為1的application,并啟動他們所在的進程
List apps = AppGlobals.getPackageManager().
getPersistentApplications(STOCK_PM_FLAGS);
if (apps != null) {
int N = apps.size();
int i;
for (i=0; i<N; i++) {
ApplicationInfo info
= (ApplicationInfo)apps.get(i);
if (info != null &&
!info.packageName.equals("android")) {
addAppLocked(info, false, null /* ABI override */);
}
}
//啟動HomeActivity,也就是launcher程序
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
……
}
}
SystemReady方法也是比較長,大致可以分為四個部分
第一:在systemReady的時候初始化了deviceIdleController等對象
第二:移除并殺死了那些不該在AMS之前啟動的進程
第三:執(zhí)行了參數(shù)傳入的回調(diào)函數(shù)
第四:啟動了Launcer界面
第五:啟動那些persistent配置為1的進程。
再來看些systemReady參數(shù)的回調(diào)函數(shù)做了什么工作.
try {
//ams開始監(jiān)聽native層的crash信息
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
//初始化webVew
WebViewFactory.prepareWebViewInSystemServer();
try {
//啟動systemUI
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
try {
//調(diào)用其他服務的systemready方法
if (networkScoreF != null) networkScoreF.systemReady();
} catch (Throwable e) {
reportWtf("making Network Score Service ready", e);
}
……
?這個回調(diào)函數(shù)中主要工作就是啟動systemUI并調(diào)用其他服務的systemReady方法,SystemReady函數(shù)完成了系統(tǒng)就緒的必要的工作,啟動了HomeActivity和SystemUI,然后Android系統(tǒng)就全部啟動了。
AMS服務啟動主要分為幾個步驟。
1. 創(chuàng)建了SystemServer進程的運行環(huán)境,包括一個ActivityThread主線程,一個和系統(tǒng)進程相關的Context對象。
2. 調(diào)用AMS的構造方法和start方法,對AMS必要的內(nèi)容進行初始化
3. 將函數(shù)AMS注冊到ServiceManager中,同時對systemServer進程也創(chuàng)建了一個ProcessRecord對象,并設置Context的appliation為framework-res的application對象
4. 將settingsProvider加載到系統(tǒng)進程systemServer中
5. 調(diào)用systemReady方法做一些啟動前的就緒工作,并啟動了HomeActivity和SystemUI