跟着
邓凡平
大神的博客走一遍加深理解。
AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度
及应用进程的管理和调度
等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要。
ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
ActivityManager
类。由于AMS是系统核心服务,很多API不能开放供客户端使用,所以设计者没有让ActivityManager直接加入AMS家族。在ActivityManager
类内部通过调用AMN的getDefault
函数得到一个ActivityManagerProxy
对象,通过它可与AMS通信。AMS由SystemServer的ServerThread线程创建,提取它的调用轨迹,代码如下:
//path:SystemServer.java::initAndLoop()
//1.Boolean:factoryTest SystemProperties.get("ro.factorytest");是否厂测
Context context=ActivityManagerService.main(factoryTest);
//2.setSystemProcess:这样SystemServer进程可加到AMS中,并被它管理
ActivityManagerService.setSystemProcess();
//3.installSystemProviders:将SettingsProvider放到SystemServer进程中来运行
ActivityManagerService.installSystemProviders();
//4.在内部保存WindowManagerService(以后简称WMS)
ActivityManagerService.self().setWindowManager(wm);
//5.AMS是系统的核心,只有它准备好后,才能调用其他服务的systemReady,少量之前那完成。
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
ActivityManagerService.self().startObservingNativeCrashes();
// 如此,状态栏就准备好了
//SystemUIService由SystemUi.apk提供,它实现了系统的状态栏。
if (!headless) startSystemUi(contextF);
if (mountServiceF != null) mountServiceF.systemReady();
if (batteryF != null) batteryF.systemReady();
if (networkManagementF != null) networkManagementF.systemReady();
if (networkStatsF != null) networkStatsF.systemReady();
if (networkPolicyF != null) networkPolicyF.systemReady();
if (connectivityF != null) connectivityF.systemReady();
if (dockF != null) dockF.systemReady();
if (usbF != null) usbF.systemReady();
if (twilightF != null) twilightF.systemReady();
if (uiModeF != null) uiModeF.systemReady();
if (recognitionF != null) recognitionF.systemReady();
Watchdog.getInstance().start();
// TODO:It is now okay to let the various system services start their third party code...
if (appWidgetF != null) appWidgetF.systemRunning(safeMode);
if (wallpaperF != null) wallpaperF.systemRunning();
if (immF != null) immF.systemRunning(statusBarF);
if (locationF != null) locationF.systemRunning();
if (countryDetectorF != null) countryDetectorF.systemRunning();
if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
if (commonTimeMgmtServiceF != null) commonTimeMgmtServiceF.systemRunning();
...
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
将分析除了4外的掉用。
AMS的main函数将返回一个Context类型的对象,该对象在SystemServer中被其他服务大量使用。Context,顾名思义,代表了一种上下文环境,有了这个环境,我们就可以做很多事情(例如获取该环境中的资源、Java类信息等)。
//ActivityManagerService.java
public static final Context main(int factoryTest) {
//线程中完成:
//1.ActivityManagerService m = new ActivityManagerService();
//mService = m;通知实例好了,则thr.mService!=null
AThread thr = new AThread();
thr.start();
while (thr.mService == null) thr.wait();//收到通知,继续
ActivityManagerService m = thr.mService;
mSelf = m;
//2.ActivityThread它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。
ActivityThread at = ActivityThread.systemMain();
mSystemThread = at;
//3.接口获取并操作Application对应的资源、类,甚至包含于Application中的四大组件。
Context context = at.getSystemContext();
context.setTheme(android.R.style.Theme_Holo);
m.mContext = context;
m.mFactoryTest = factoryTest;
m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
//AMS中用来管理Activity的启动和调度的核心类
m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
m.mBatteryStatsService.publish(context);
m.mUsageStatsService.publish(context);
m.mAppOpsService.publish(context);
thr.mReady = true;
thr.notifyAll();
//4.启动startRunning函数
m.startRunning(null, null, null, null);
return context;
}
在main函数中,完成mSystemThread
等全局变量填充和调用了startRunning
函数.。主要分析·ActivityManagerService`构造函数。
和几个全局变量。
AMS的构造函数的代码如下:
private ActivityManagerService() {
//创建广播队列(前台和后台队列)
mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
//service和provider
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
//创建/data/system/
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
// 电源服务一些信息/data/system/batterystats.bin
mBatteryStatsService = new BatteryStatsService(new File(
systemDir, "batterystats.bin").toString());
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
mOnBattery = DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
mBatteryStatsService.getActiveStatistics().setCallback(this);
//进程状态 /data/system/procstates
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
//使用状态 /data/system/usagestats
mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
// Ops状态 /data/system/appops.xml
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
// Uri授权记录 /data/system/urigrants.xml
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
// User 0 is the first and only user that runs at boot.
mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
mUserLru.add(Integer.valueOf(0));
updateStartedUserArrayLocked();
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
//mConfiguration类型为Configuration,用于描述资源文件的配置属性,
//例如字体、语言等。后文再讨论这方面的内容
mConfiguration.setToDefaults();
mConfiguration.setLocale(Locale.getDefault());
mConfigurationSeq = mConfiguration.seq = 1;
mProcessCpuTracker.init();
mCompatModePackages = new CompatModePackages(this, systemDir);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
mProcessCpuThread = new Thread("CpuTracker"){
@Override
public void run() {
while (true) {
final long now = SystemClock.uptimeMillis();
long nextCpuDelay =(mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
//Slog.i(TAG, "Cpu delay=" + nextCpuDelay
// + ", write delay=" + nextWriteDelay);
if (nextWriteDelay < nextCpuDelay) {
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
mProcessCpuMutexFree.set(true);
this.wait(nextCpuDelay);
}
updateCpuStatsNow();
}
}
};
mProcessCpuThread.start();
}
构造函数完成了:
mFgBroadcastQueue
和mBgBroadcastQueue
两个广播队列。/data/system/
目录下一些信息,如:/data/system/procstates
等注意:应用进程指那些运行APK的进程,它们由Zyote 派生(fork)而来,上面运行了dalvik虚拟机。与应用进程相对的就是系统进程(包括Zygote和SystemServer)。
“应用进程和系统进程”与“应用APK和系统APK”的概念区分开来。APK的判别依赖其文件所在位置(如果apk文件在/data/app目录下,则为应用APK)。
public static ActivityThread systemMain() {
//禁止硬件加速
HardwareRenderer.disable(true);
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
前面所说的ActivityThread代表应用进程(其上运行了APK)的主线程,而SystemServer并非一个应用进程,那么为什么此处也需要ActivityThread呢?
//system=true
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {//应用进程处理流程
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("" ,UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {//系统处理流程,systemServer中对应这个.
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
//设置DDMS看到systemserver进程名为system_process
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {//Activity几员大将出场
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
Application app = Instrumentation.newApplication(Application.class, context);
//一个进程支持多个应用
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
// add dropbox logging to libcore
DropBox.setReporter(new DropBoxReporter());
//监听配置改变,如语言切换时,需要调用。
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
Activity几员大将出场:
Instrumentation
:一个工具类。当它被启用时,系统先创建它,再通过它来创建其他组件。系统和组件之间的交互也将通过Instrumentation来传递,这样,Instrumentation就能监测系统和这些组件的交互情况了。在实际使用中,我们可以创建Instrumentation的派生类来进行相应的处理。Application
:保存了一个全局的application状态。Application由AndroidManifest.xml中的
标签声明。在实际使用时需定义Application的派生类。Application是Android中的一个概念,可理解为一种容器,它内部包含四大组件。另外,一个进程可以运行多个Application。Context
是一个接口,通过它可以获取并操作Application
对应的资源、类,甚至包含于Application中的四大组件。Context是一个抽象类,而由AMS创建的将是它的子类ContextImpl。 public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
ContextImpl context =
ContextImpl.createSystemContext(this);
//LoadedApk代表一个加载到系统中的APK
LoadedApk info = new LoadedApk(this, "android", context, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
context.init(info, null, this);
//初始化资源信息
context.getResources().updateConfiguration
(mResourcesManager.getConfiguration(),
getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
mSystemContext = context;
//Slog.i(TAG, "Created system resources " + context.getResources()
// + ": " + context.getResources().getConfiguration());
}
}
return mSystemContext;
}
为什么函数名是getSystemContext
呢?
初始化ContextImp
时使用了一个LoadedApk对象,package
名为android
,,其实就是framework-res.apk,为了加载该APK。
上述类中关系图:
先来看派生关系, ApplicationContentResolver从ConentResolver派生,它主要用于和ContentProvider打交道。ContextImpl和ContextWrapper均从Context继承,而Application则从ContextWrapper派生。
ContextWrapper
是一个代理类,被代理的对象是另外一个Context
。被代理的类其实是ContextImpl
,由ContextWrapper
通过mBase成员变量指定。其内部函数功能的实现最终都由mBase完成。这样设计的目的是想把ContextImpl隐藏起来。Application
从ContextWrapper
派生,并实现了ComponentCallbacks2
接口。Application中有一个LoadedApk
类型的成员变量mLoadedApk
。LoadedApk代表一个APK文件。由于一个AndroidManifest.xml
文件只能声明一个Application标签
,所以一个Application必然会和一个LoadedApk绑定。Service
从ContextWrapper
派生,其中Service内部成员变量mApplication
指向Application(在AndroidManifest.xml
中,Service只能作为Application
的子标签,所以在代码中Service
必然会和一个Application
绑定)。ContextThemeWrapper
重载了和Theme
(主题)相关的两个函数。这些和界面有关,所以Activity
作为Android系统中的UI容器,必然也会从ContextThemeWrapper
派生。与Service
一样,Activity内部也通过mApplication
成员变量指向Application
。systemMain函数总结
调用systemMain函数结束后,我们得到了什么?
systemMain函数将为SystemServer进程搭建一个和应用进程一样的Android运行环境。这句话涉及两个概念。
- 进程:来源于操作系统,是在OS中看到的运行体。我们编写的代码一定要运行在一个进程中。
- Android运行环境:Android努力构筑了一个自己的运行环境。在这个环境中,进程的概念被模糊化了。组件的运行及它们之间的交互均在该环境中实现。
Android运行环境是构建在进程之上的。在应用程序中,一般只和Android运行环境交互。基于同样的道理,SystemServer希望它内部的那些Service也通过Android运行环境交互,因此也需为它创建一个运行环境。由于SystemServer的特殊性,此处调用了systemMain函数,而普通的应用进程将在主线程中调用ActivityThread的main函数来创建Android运行环境。
另外,ActivityThread虽然本意是代表进程的主线程,但是作为一个Java类,它的实例到底由什么线程创建,恐怕不是ActivityThread自己能做主的,所以在SystemServer中可以发现,ActivityThread对象由其他线程创建,而在应用进程中,ActivityThread将由主线程来创建。
public final void startRunning(String pkg, String cls, String action, String data) {
synchronized(this) {
if (mStartRunning) {
return;
}
mStartRunning = true;
//mTopComponent最终赋值为null
mTopComponent = pkg != null && cls != null
? new ComponentName(pkg, cls) : null;
//mTopAction= Intent.ACTION_MAIN
mTopAction = action != null ? action : Intent.ACTION_MAIN;
mTopData = data;//mTopData最终为null
if (!mSystemReady) {
return;
}
}
//这个函数很重要,可惜不在本次startRunning中调用
systemReady(null);
}
public static void setSystemProcess() {
try {
ActivityManagerService m = mSelf;
//向ServiceManager注册几个服务
ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));//显示加速方面的信息(Applications
Graphics Acceleration Info), dumpsys gfxinfo
ServiceManager.addService("dbinfo", new DbBinder(m));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(m));
}
//向SM注册权限管理服务PermissionController
ServiceManager.addService("permission", new PermissionController(m));
//虽然PKMS和AMS同属一个进程,但是二者交互仍然借助Context 其实,此处完全可以直接调用PKMS的函数。为什么要费如此周折呢
ApplicationInfo info =
mSelf.mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
//1.installSystemApplicationInfo
mSystemThread.installSystemApplicationInfo(info);
synchronized (mSelf) {//2.此处涉及AMS对进程的管理,processName=system
ProcessRecord app = mSelf.newProcessRecordLocked(info,
info.processName, false);
//这里标识出systemProcess
app.persistent = true;//设置该值为true
app.pid = MY_PID;//设置pid为SystemServer的进程号
app.maxAdj = ProcessList.SYSTEM_ADJ;//设置最大OOM_Adj,系统进程默认值为-16
app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
//3.保存该ProcessRecord对象
mSelf.mProcessNames.put(app.processName, app.uid, app);
synchronized (mSelf.mPidsSelfLocked) {
mSelf.mPidsSelfLocked.put(app.pid, app);
}
//根据系统当前状态,调整进程的调度优先级和OOM_Adj,后续将详细分析该函数
mSelf.updateLruProcessLocked(app, false, null);
mSelf.updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
在以上代码中列出了一个重要说明和两个关键点。
AMS通过Context查询PKMS中一个名为“android”的package得来,只有framework-res.apk声明其package名为“android”。
public void installSystemApplicationInfo(ApplicationInfo info) {
synchronized (this) {
//返回的ContextImpl对象即之前在AMS的main函数一节中创建的那个对象
ContextImpl context = getSystemContext();
//又调用init初始化该Context,是不是重复调用init了?
context.init(new LoadedApk(this, "android", context, info,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
// give ourselves a default profiler
//创建一个Profiler对象,用于性能统计
mProfiler = new Profiler();
}
}
又调用init初始化该Context,是不是重复调用init了?
mSelf.newProcessRecordLocked
函数AMS和应用进程交互,如启动其他进程的Activity,由于该Activity在另一个进程中,需要跨进程通信,通过Binder
完成。Android提供了IApplicationThread接口,该接口定义了AMS和应用进程之间交互函数。
public interface IApplicationThread extends IInterface {
void schedulePauseActivity;
void scheduleStopActivity;
void scheduleWindowVisibility;
void scheduleSleeping;
void scheduleResumeActivity
void scheduleLaunchActivity
void scheduleReceiver
void scheduleCreateService
void scheduleRegisteredReceiver
void scheduleLowMemory()
void setProcessState
}
newProcessRecordLocked函数
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
boolean isolated) {
String proc = customProcess != null ? customProcess : info.processName;
BatteryStatsImpl.Uid.Proc ps = null;
//BSImpl将为该进程创建一个耗电量统计项
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
int uid = info.uid;
if (isolated) {
int userId = UserHandle.getUserId(uid);
int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
while (true) {
if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
|| mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
}
uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
mNextIsolatedProcessUid++;
if (mIsolatedProcesses.indexOfKey(uid) < 0) {
// No process for this uid, use it.
break;
}
stepsLeft--;
if (stepsLeft <= 0) {
return null;
}
}
}
//创建一个ProcessRecord对象,用于和其他进程通信的thread作为第一个参数
return new ProcessRecord(stats, info, proc, uid);
}
ProcessRecord构造函数初始化一些成员变量:
ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
String _processName, int _uid) {
mBatteryStats = _batteryStats; //用于电量统计
info = _info;//保存ApplicationInfo
isolated = _info.uid != _uid;
uid = _uid;
userId = UserHandle.getUserId(_uid);
processName = _processName; //保存进程名
pkgList.put(_info.packageName, null);//一个进程能运行多个Package,pkgList用于保存package名
//下面这些xxxAdj成员变量和进程调度优先级及OOM_adj有关。
maxAdj = ProcessList.UNKNOWN_ADJ;
curRawAdj = setRawAdj = -100;
curAdj = setAdj = -100;
//用于控制该进程是否常驻内存(即使被杀掉,系统也会重启它),只有重要的进程才会有此待遇
persistent = false;
removed = false;
lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
}
AMS的setSystemProcess总结
现在来总结回顾setSystemProcess的工作:
该Provider
在SettingsProvider.apk中,installSystemProviders
就会加载该APK
并把SettingsProvider
放到SystemServer
进程中来运行。此时的SystemServer已经加载了framework-res.apk,现在又要加载另外一个APK文件,这就是多个APK运行在同一进程的典型案例。另外,通过installSystemProviders函数还能见识ContentProvider的安装过程,下面就来分析它。
public static final void installSystemProviders() {
List providers;
synchronized (mSelf) {
/*从mProcessNames找到进程名为“system”且uid为SYSTEM_UID的ProcessRecord,返回值就是前面在installSystemApplication中创建的那个ProcessRecord,它代表SystemServer进程 */
ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
//1.关键调用,见下文分析
providers = mSelf.generateApplicationProvidersLocked(app);
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) {
//将非系统APK(即未设ApplicationInfo.FLAG_SYSTEM标志)提供的Provider从providers列表中去掉
Slog.w(TAG, "Not installing system proc provider " + pi.name
+ ": not system .apk");
providers.remove(i);
}
}
}
}
if (providers != null) {
//2.为SystemServer进程安装Provider
mSystemThread.installSystemProviders(providers);
}
//监视Settings数据库中Secure表的变化,目前只关注long_press_timeout配置的变化
mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
mSelf.mUsageStatsService.monitorPackages();
}
在代码中列出了两个关键调用,分别是:
AMS的 generateApplicationProvidersLocked
函数分析
private final List generateApplicationProvidersLocked(ProcessRecord app) {
List providers = null;
try {
//1.向PKMS查询满足要求的ProviderInfo,最重要的查询条件包括:进程名和进程uid
providers = AppGlobals.getPackageManager().
queryContentProviders(app.processName, app.uid,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
} catch (RemoteException ex) {
}
if (DEBUG_MU)
Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
int userId = app.userId;
if (providers != null) {
int N = providers.size();
app.pubProviders.ensureCapacity(N + app.pubProviders.size());
for (int i=0; i//2.AMS对ContentProvider的管理,见下文解释
ProviderInfo cpi =
(ProviderInfo)providers.get(i);
boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
cpi.name, cpi.flags);
if (singleton && UserHandle.getUserId(app.uid) != 0) {
// 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 comp = new ComponentName(cpi.packageName, cpi.name);
//ContentProvider在AMS中用ContentProviderRecord来表示
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
if (cpr == null) {
cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
mProviderMap.putProviderByClass(comp, cpr);
}
if (DEBUG_MU)
Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
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.
app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
}
ensurePackageDexOpt(cpi.applicationInfo.packageName);
}
}
return providers;
}
由以上代码可知:generateApplicationProvidersLocked先从PKMS那里查询满足条件的ProviderInfo信息,而后将它们分别保存到AMS和ProcessRecord中对应的数据结构中。
先看查询函数queryContentProviders。
public List queryContentProviders(String processName,
int uid, int flags) {
ArrayList finalList = null;
// reader
synchronized (mPackages) {
final Iterator i = mProviders.mProviders.values().iterator();
final int userId = processName != null ?
UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Provider p = i.next();
PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
// 下面的if语句将从这些Provider中搜索本例设置的processName为“system”,uid为SYSTEM_UID,flags为FLAG_SYSTEM的Provider
if (ps != null && p.info.authority != null
&& (processName == null
|| (p.info.processName.equals(processName)
&& UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
&& mSettings.isEnabledLPr(p.info, flags, userId)
&& (!mSafeMode
|| (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
if (finalList == null) {
finalList = new ArrayList(3);
}
ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
ps.readUserState(userId), userId);
if (info != null) {
finalList.add(info);
}
}
}
}
//由PackageParser.Provider得到ProviderInfo,并添加到finalList中
if (finalList != null) {
//最终结果按provider的initOrder排序,该值用于表示初始化ContentProvider的顺序
Collections.sort(finalList, mProviderInitOrderSorter);
}
return finalList;
}
queryContentProviders函数很简单,就是从PKMS那里查找满足条件的Provider,然后生成AMS使用的ProviderInfo信息。为何偏偏能找到SettingsProvider呢?来看它的AndroidManifest.xml
文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.providers.settings"
coreApp="true"
android:sharedUserId="android.uid.system">
<application android:allowClearUserData="false"
android:label="@string/app_label"
android:process="system"
android:backupAgent="SettingsBackupAgent"
android:killAfterRestore="false"
android:icon="@mipmap/ic_launcher_settings">
<provider android:name="SettingsProvider" android:authorities="settings"
android:multiprocess="false"
android:exported="true"
android:writePermission="android.permission.WRITE_SETTINGS"
android:initOrder="100" />
application>
manifest>
SettingsProvider设置了其uid为“android.uid.system”,同时在application中设置了process名为“system”。而在framework-res.apk中也做了相同的设置。所以,现在可以确认SettingsProvider将和framework-res.apk运行在同一个进程,即SystemServer中。
提示从运行效率角度来说,这样做也是合情合理的。因为SystemServer的很多Service都依赖Settings数据库,把它们放在同一个进程中,可以降低由于进程间通信带来的效率损失。
AMS的systemReady代码较多,会做什么,将会分为三个阶段。
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {//SystemReady,则直接执行线程
if (goingCallback != null) goingCallback.run();
return;
}
if(SystemProperties.get("persist.sys.qb.enable","false").equals("true")){
reloadConfiguration();
}
// Check to see if there are any update receivers to run.是否有升级动作
if (!mDidUpdate) {
if (mWaitingUpdate) {
return;
}
//准备PRE_BOOT_COMPLETED广播
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
List ris = null;
try {
// //向PKMS查询该广播的接收者
ris = AppGlobals.getPackageManager().queryIntentReceivers(
intent, null, 0, 0);
} catch (RemoteException e) {
}
if (ris != null) {
for (int i=ris.size()-1; i>=0; i--) {
if ((ris.get(i).activityInfo.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) == 0) {
ris.remove(i);
}
}//从返回的结果中删除那些非系统APK的广播接收者
//读取/data/system/called_pre_boots.dat文件,这里存储了上次启动时候已经
//接收并处理PRE_BOOT_COMPLETED广播的组件。鉴于该广播的特殊性,系统希望
//该广播仅被这些接收者处理一次
intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
ArrayList lastDoneReceivers = readLastDonePreBootReceivers();
final ArrayList doneReceivers = new ArrayList();
for (int i=0; inew ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
ris.remove(i);
i--;
}//从PKMS返回的接收者中删除那些已经处理过该广播的对象
}
final int[] users = getUsersLocked();
for (int i=0; inew ComponentName(ai.packageName, ai.name);
doneReceivers.add(comp);
intent.setComponent(comp);
for (int j=0; jnull;
//为最后一个广播接收者注册一个回调通知,当该接收者处理完广播后,将调用该回调
if (i == ris.size()-1 && j == users.length-1) {
finisher = new IIntentReceiver.Stub() {
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
// The raw IIntentReceiver interface is called
// with the AM lock held, so redispatch to
// execute our code without the lock.
mHandler.post(new Runnable() {
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
//保存那些处理过该广播的接收者信息 writeLastDonePreBootReceivers(doneReceivers);
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
systemReady(goingCallback);
}
});
}
};
}
Slog.i(TAG, "Sending system update to " + intent.getComponent()
+ " for user " + users[j]);
+
broadcastIntentLocked(null, null, intent, null, finisher,
0, null, null, null, AppOpsManager.OP_NONE,
true, false, MY_PID, Process.SYSTEM_UID,
users[j]);
if (finisher != null) {
mWaitingUpdate = true;
}
}
}
}
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
//调用AppOpsService.systemReady()
mAppOpsService.systemReady();
mSystemReady = true;
if (!mStartRunning) {
return;
}
systemReady第一阶段的工作并不轻松,其主要职责是发送并处理与PRE_BOOT_COMPLETED广播相关的事情。目前代码中还没有接收该广播的地方,不过从代码中的注释中可猜测到,该广播接收者的工作似乎和系统升级有关。
ArrayList procsToKill = null;
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();
}
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);
//把这些进程关闭,removeProcessLocked
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.
//至此,系统已经准备完毕
mProcessesReady = true;
}
Slog.i(TAG, "System now ready");
if(checkQbVersion())
{
Slog.i("Qb","System now ready");
getQbAndroidManager();
mQbFlag = mQbAndroidManager.checkFlag();
}
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
SystemClock.uptimeMillis());
synchronized(this) {
// Make sure we have no pre-ready processes sitting around.
//和工厂测试有关,不对此进行讨论
if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
ResolveInfo ri = mContext.getPackageManager()
.resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
STOCK_PM_FLAGS);
CharSequence errorMsg = null;
if (ri != null) {
ActivityInfo ai = ri.activityInfo;
ApplicationInfo app = ai.applicationInfo;
if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
mTopAction = Intent.ACTION_FACTORY_TEST;
mTopData = null;
mTopComponent = new ComponentName(app.packageName,
ai.name);
} else {
errorMsg = mContext.getResources().getText(
com.android.internal.R.string.factorytest_not_system);
}
} else {
errorMsg = mContext.getResources().getText(
com.android.internal.R.string.factorytest_no_action);
}
if (errorMsg != null) {
mTopAction = null;
mTopData = null;
mTopComponent = null;
Message msg = Message.obtain();
msg.what = SHOW_FACTORY_ERROR_MSG;
msg.getData().putCharSequence("msg", errorMsg);
mHandler.sendMessage(msg);
}
}
}
//查询Settings数据,获取一些配置参数
retrieveSettings();
systemReady第二阶段的工作包括:
synchronized (this) {
readGrantedUriPermissionsLocked();
}
//调用systemReady传入的参数,它是一个Runnable对象,下节将分析此函数
if (goingCallback != null) goingCallback.run();
synchronized (this) {
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
//从PKMS中查询那些persistent为1的ApplicationInfo
List apps = AppGlobals.getPackageManager().
getPersistentApplications(STOCK_PM_FLAGS);
if (apps != null) {
int N = apps.size();
int i;
for (i=0; i//由于framework-res.apk已经由系统启动,所以这里需要把它去除
//framework-res.apk的packageName为"android"
if (info != null &&
!info.packageName.equals("android")) {
addAppLocked(info, false);//启动该Application所在的进程
}
}
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
}
// Start up initial activity.设置mBooting=true
mBooting = true;
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
Message msg = Message.obtain();
msg.what = SHOW_UID_ERROR_MSG;
mHandler.sendMessage(msg);//处理那些Uid有错误的Application
}
} catch (RemoteException e) {
}
long ident = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null, AppOpsManager.OP_NONE,
false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(null, null, intent,
null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
}
}, 0, null, null,
android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
}
//启动全系统第一个Activity,即Home
mStackSupervisor.resumeTopActivitiesLocked();
sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
}
systemReady第三阶段的工作有3项: