基于Android 6.0的源码剖析, 分析Android系统服务ActivityManagerService,简称AMS
frameworks/base/core/java/android/app/
- ActivityThread.java
- LoadedApk.java
- ContextImpl.java
frameworks/base/services/java/com/android/server/
- SystemServer.java
frameworks/base/services/core/java/com/android/server/
- SystemServiceManager.java
- ServiceThread.java
- pm/Installer.java
- am/ActivityManagerService.java
一、概述
本文以AMS为主线,讲述system_server进程中AMS服务的启动过程,以startBootstrapServices()方法为起点,紧跟着startCoreServices(), startOtherServices()共3个方法。本文大致流程:
二. AMS启动过程
2.1 startBootstrapServices
[-> SystemServer.java]
private void startBootstrapServices() {
...
//启动AMS服务【见小节2.2】
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//设置AMS的系统服务管理器
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//设置AMS的APP安装器
mActivityManagerService.setInstaller(installer);
//初始化AMS相关的PMS
mActivityManagerService.initPowerManagement();
...
//设置SystemServer【见小节2.3】
mActivityManagerService.setSystemProcess();
}
2.2 启动AMS服务
SystemServiceManager.startService(ActivityManagerService.Lifecycle.class) 功能主要:
SystemServiceManager.startService返回Lifecycle对象,并调用Lifecycle.onStart()方法
- 创建ActivityManagerService.Lifecycle对象;
- 调用Lifecycle.onStart()方法。
2.1.1 AMS.Lifecycle
[-> ActivityManagerService.java]
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
//创建ActivityManagerService【见小节2.1.2】
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start(); //【见小节2.1.3】
}
public ActivityManagerService getService() {
return mService;
}
}
该过程:创建AMS内部类的Lifecycle,已经创建AMS对象,并调用AMS.start();
2.1.2 AMS创建
public ActivityManagerService(Context systemContext) {
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();//默认为FACTORY_TEST_OFF
mSystemThread = ActivityThread.currentActivityThread();
//创建名为"ActivityManager"的前台线程,并获取mHandler
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
//通过UiThread类,创建名为"android.ui"的线程
mUiHandler = new UiHandler();
//前台广播接收器,在运行超过10s将放弃执行
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
//后台广播接收器,在运行超过60s将放弃执行
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
//创建ActiveServices,其中非低内存手机mMaxStartingBackground为8
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
//创建目录/data/system
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
//创建服务BatteryStatsService
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
...
//创建进程统计服务,信息保存在目录/data/system/procstats,
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"));
// User 0是第一个,也是唯一的一个开机过程中运行的用户
mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
mUserLru.add(UserHandle.USER_OWNER);
updateStartedUserArrayLocked();
...
//CPU使用情况的追踪器执行初始化
mProcessCpuTracker.init();
...
mRecentTasks = new RecentTasks(this);
// 创建ActivityStackSupervisor对象
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
//创建名为"CpuTracker"的线程
mProcessCpuThread = new Thread("CpuTracker") {
public void run() {
while (true) {
try {
try {
synchronized(this) {
final long now = SystemClock.uptimeMillis();
long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
if (nextWriteDelay < nextCpuDelay) {
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
mProcessCpuMutexFree.set(true);
this.wait(nextCpuDelay);
}
}
} catch (InterruptedException e) {
}
updateCpuStatsNow(); //更新CPU状态
} catch (Exception e) {
}
}
}
};
...
}
该过程共创建了3个线程,分别为”ActivityManager”,”android.ui”,”CpuTracker”。
- 以上 AMS创建过程 涉及到Android 四大组件管理的初始化:
Broadcast --》BroadcastQueue
Provider --》ProviderMap
Service --》ActiveServices
Activity --》ActivityStackSupervisor
2.1.3 AMS.start
private void start() {
Process.removeAllProcessGroups(); //移除所有的进程组
mProcessCpuThread.start(); //启动CpuTracker线程
mBatteryStatsService.publish(mContext); //启动电池统计服务
mAppOpsService.publish(mContext);
//创建LocalService,并添加到LocalServices
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
2.3 AMS.setSystemProcess
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
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));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
//【见小节2.3.1】
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
//创建ProcessRecord对象
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true; //设置为persistent进程
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);//维护进程lru
updateOomAdjLocked(); //更新adj
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("", e);
}
}
setSystemProcess意义:
主要工作是注册各种服务。
这一步就是给SystemServer进程创建ProcessRecord,adj值,就是将SystemServer进程加入到AMS进程管理机制中,跟应用进程一致;
进程调度更新优先级oomadj值,个人感觉SystemServer进程跟应用进程就不一样,却加入AMS来调度管理,这样做的意义何在?
2.4 startOtherServices
private void startOtherServices() {
...
//安装系统Provider 【见小节2.4.1】
mActivityManagerService.installSystemProviders();
//通过WMS 弹出“正在启动应用”框
ActivityManagerNative.getDefault().showBootMessage(context.getResources().getText(
com.android.internal.R.string.android_upgrading_starting_apps),false);
...
mActivityManagerService.systemReady(new Runnable() {
public void run() {
//phase550
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
mActivityManagerService.startObservingNativeCrashes();
//启动WebView
WebViewFactory.prepareWebViewInSystemServer();
//启动系统UI【见小节3.2.1】
startSystemUi(context);
// 执行一系列服务的systemReady方法
networkScoreF.systemReady();
networkManagementF.systemReady();
networkStatsF.systemReady();
networkPolicyF.systemReady();
connectivityF.systemReady();
audioServiceF.systemReady();
Watchdog.getInstance().start(); //Watchdog开始工作
//phase600
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
//执行一系列服务的systemRunning方法
wallpaper.systemRunning();
inputMethodManager.systemRunning(statusBarF);
location.systemRunning();
countryDetector.systemRunning();
networkTimeUpdater.systemRunning();
commonTimeMgmtService.systemRunning();
textServiceManagerService.systemRunning();
assetAtlasService.systemRunning();
inputManager.systemRunning();
telephonyRegistry.systemRunning();
mediaRouter.systemRunning();
mmsService.systemRunning();
}
});
}
该过程启动各种进程:
- 启动阶段550,回调相应onBootPhase()方法;
- 启动WebView,并且会创建进程,这是zygote正式创建的第一个进程;
- 启动systemui服务;
- installSystemProviderss,加载SettingsProvider;
- 通过WMS 弹出“正在启动应用”框
2.4.1 startSystemUi
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
context.startServiceAsUser(intent, UserHandle.OWNER);
}
启动服务”com.android.systemui/.SystemUIService”
三. AMS.systemReady
v
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
goingCallback.run();
}
……
// 1.升级相关处理:发送PRE_BOOT_COMPLETED广播 等待升级处理完成才能继续
// Check to see if there are any update receivers to run.
if (!mDidUpdate) {
// 等待升级完成,否则直接返回
if (mWaitingUpdate) {
return;
}
// 发送PRE_BOOT_COMPLETED广播
final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();//分析见3.2
mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
// 等待所有接收PRE_BOOT_COMPLETED广播者处理完毕
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
// 将系统版本号和处理过的广播写入文件:/data/system/called_pre_boots.dat文件
writeLastDonePreBootReceivers(doneReceivers);
// 继续systemReady流程
systemReady(goingCallback);
}
}, doneReceivers, UserHandle.USER_OWNER);
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
mSystemReady = true;
}
// 2. 收集已经启动的进程并杀死,除过persistent常驻进程
ArrayList<ProcessRecord> 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<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);
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;
}
// 3.系统准备好后回调传入的Runnable:
if (goingCallback != null) goingCallback.run();
// 4. 发送账户启动的广播,涉及多用户
long ident = Binder.clearCallingIdentity();
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
broadcastIntentLocked(intent);
intent = new Intent(Intent.ACTION_USER_STARTING);
broadcastIntentLocked(intent);
Binder.restoreCallingIdentity(ident);
// 5. 启动桌面Home Activity分析见3.1
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
mStackSupervisor.resumeTopActivitiesLocked();
}
该阶段的主要功能:
- 向PRE_BOOT_COMPLETED的接收者发送广播;
- 杀掉procsToKill中的进程, 杀掉进程且不允许重启;
- 此时,系统和进程都处于ready状态;
- 回调所有SystemService的onStartUser()方法;
- 启动persistent进程;
- 启动home Activity;
- 发送广播USER_STARTED和USER_STARTING;
- 恢复栈顶Activity;
Q1: 系统都有哪些地方接收PRE_BOOT_COMPLETED,以及什么情况下应该接收该广播?
从目前看到的主要应用在数据库应用升级方面,数据库升级涉及到数据字段变化,数据的增加等会比较耗时,
为了加快应用启动和提供数据,需要在开机过程中做升级操作,避免使用时耗时。
Q2: 这里其实存在一个隐患:从上面的流程看到,系统发送广播给接收者处理,只有等所有接收者处理完毕,才会继续系统的启 动流程。
试想:如果某个接收者的操作处理耗时较长,甚至被阻塞 或其他异常导致广播处理无法完成,不能回调回来怎么办?
结果:开机时间需要的更长了,或无法开机,一直就卡在这里无法开机。
这其实是系统不合理的地方,没有相应的超时控制的安全机制,所幸这里只允许系统应用接收该广播,如果允许第三方接收,后果可想而知。
3.1AMS.startHomeActivityLocked
boolean startHomeActivityLocked(int userId, String reason) {
//home intent有CATEGORY_HOME
Intent intent = getHomeIntent();
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);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
//启动桌面Activity
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}
}
return true;
}
3.2 deliverPreBootCompleted
deliverPreBootCompleted(new Runnable() {
// 向PMS查询,所有接收ACTION_PRE_BOOT_COMPLETED广播的Receiver
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
List<ResolveInfo> ris = null;
ris = AppGlobals.getPackageManager().queryIntentReceivers(
intent, null, 0, userId);
// 只有系统广播才能接收该广播,去掉非系统应用
for (int i=ris.size()-1; i>=0; i--) {
if ((ris.get(i).activityInfo.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) == 0) {
ris.remove(i);
}
}
// 给Intent设置flag:FLAG_RECEIVER_BOOT_UPGRADE,很关键这个看看flag的作用:
// 只有设置这个标志,才能让应用在系统没有ready的情况下启动,见下文原始注释
intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
// 将已经处理过ACTION_PRE_BOOT_COMPLETED广播的Receiver去掉
// 已经处理该广播的Receiver记录 和 对应的系统版本号 都记录在:/data/system/called_pre_boots.dat文件中,
// 通过与系统当前版本号比对,确认是否已处理过。考虑处理过程异常中断的情况:比如断电
ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
// 将已经处理过的广播去除,同时记录已处理过保存在 doneReceivers数组中
for (int i=0; i<ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
// We already did the pre boot receiver for this app with the current
// platform version, so don't do it again...
ris.remove(i);
i--;
// ...however, do keep it as one that has been done, so we don't
// forget about it when rewriting the file of last done receivers.
doneReceivers.add(comp);
}
}
// 内部类专门用来ACTION_PRE_BOOT_COMPLETED广播的发送,要看看这个PreBootContinuation类
// 这块逻辑一直在变,Android5.0, 6.0 , 以及看到在7.0上又变了,基本思路不变,本文代码基于Android6.0
//详细见3.1.2.1
PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
ris, users);
cont.go();
return true;
}
只有系统做OTA升级 和 手机初次开机的时候,应当才会走此广播,下面看看这个函数具体的处理。
public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x02000000;
3.2.1 PreBootContinuation
[-> ActivityManagerService.java ::PreBootContinuation]
final class PreBootContinuation extends IIntentReceiver.Stub {
void go() {
//判断是不是最后一个接收者
if (lastRi != curRi) {
// 疑问:如果不是最后一个接收者,则发给一个指定接收者ComponentName
// 为什么要在这里指定接收者,一个个发送,而不是交给广播自己去处理?
ActivityInfo ai = ris.get(curRi).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
intent.setComponent(comp);
doneReceivers.add(comp);
lastRi = curRi;
// 界面显示正在处理的广播,上面的指定接收者,就是为了这里能显示正在处理的广播名称?
CharSequence label = ai.loadLabel(mContext.getPackageManager());
showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
}
// 发送广播,指定接收者处理完毕,会resultTo回来--》this
Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
+ " for user " + users[curUser]);
broadcastIntentLocked(null, null, intent, null, this,
0, null, null, null, AppOpsManager.OP_NONE,
null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
}
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
// 指定接收者广播处理完毕回调resultTo回来,继续处理下一个,如果所有处理完,则post消息执行onFinishCallback
curUser++;
if (curUser >= users.length) {
curUser = 0;
curRi++;
if (curRi >= ris.size()) {
// All done sending broadcasts!
if (onFinishCallback != null) {
// The raw IIntentReceiver interface is called
// with the AM lock held, so redispatch to
// execute our code without the lock.
mHandler.post(onFinishCallback);
}
return;
}
}
go();
}
}
四. 总结
- 创建AMS实例对象,创建Andoid Runtime,ActivityThread和Context对象;
- setSystemProcess:注册AMS、meminfo、cpuinfo等服务到ServiceManager;
- installSystemProviderss,加载SettingsProvider;
- 启动SystemUIService,再调用一系列服务的systemReady()方法;
4.1 发布Binder服务
[小节2.3]的AMS.setSystemProcess()过程向servicemanager注册了如下这个binder服务
服务名 | 类名 | 功能 |
---|---|---|
activity | ActivityManagerService | AMS |
procstats | ProcessStatsService | 进程统计 |
meminfo | MemBinder | 内存 |
gfxinfo | GraphicsBinder | 图像信息 |
dbinfo | DbBinder | 数据库 |
cpuinfo | CpuBinder | CPU |
permission | PermissionController | 权限 |
processinfo | ProcessInfoService | 进程服务 |
usagestats | UsageStatsService | 应用的使用情况 |
想要查看这些服务的信息,可通过dumpsys <服务名>
命令。比如查看CPU信息命令dumpsys cpuinfo
。
4.2 AMS.systemReady
另外,AMS.systemReady()的大致过程如下:
public final class ActivityManagerService{
public void systemReady(final Runnable goingCallback) {
...//更新操作
mSystemReady = true; //系统处于ready状态
removeProcessLocked(proc, true, false, "system update done");//杀掉所有非persistent进程
mProcessesReady = true; //进程处于ready状态
goingCallback.run(); //这里有可能启动进程
addAppLocked(info, false, null); //启动所有的persistent进程
mBooting = true; //正在启动中
startHomeActivityLocked(mCurrentUserId, "systemReady"); //启动桌面
mStackSupervisor.resumeTopActivitiesLocked(); //恢复栈顶的Activity
}
}
相关文章:https://www.cnblogs.com/bastard/p/5770573.html