今天接着完善Android系统这一块的体系架构,说说在App启动流程中举足轻重的ActivityManagerService
。
顾名思义,这个组件肯定是用来管理Activity
的服务,其实不仅是Activity
,它还负责四大组件相关的启动,切换,调度等等。
具体是怎么被启动的,又是怎么进行管理的呢?一起看看吧。
(代码基于Android9.0)
之前在SystemServer
章节说过,系统的服务一般都是通过SystemServer
进程启动的,AMS也不例外。
//SystemServer.java
private void startBootstrapServices() {
//...
// Activity manager runs the show.
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
}
//中间用到了反射,之前说过。
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
}
//ActivityManagerService.java
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
@Override
public void onBootPhase(int phase) {
mService.mBootPhase = phase;
if (phase == PHASE_SYSTEM_SERVICES_READY) {
mService.mBatteryStatsService.systemServicesReady();
mService.mServices.systemServicesReady();
}
}
@Override
public void onCleanupUser(int userId) {
mService.mBatteryStatsService.onCleanupUser(userId);
}
public ActivityManagerService getService() {
return mService;
}
}
可以看到,通过调用了ActivityManagerService.Lifecycle
这个内部类中的onStart方法,启动了AMS,并调用了AMS的start方法。
再简单看看AMS的实例化方法
和start
方法:
public ActivityManagerService(Context systemContext) {
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = mInjector.getUiHandler(this);
//...
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
mAppErrors = new AppErrors(mUiContext, this);
// TODO: Move creation of battery stats service outside of activity manager service.
mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.scheduleWriteToDisk();
mOnBattery = DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
mBatteryStatsService.getActiveStatistics().setCallback(this);
mStackSupervisor = createStackSupervisor();
mStackSupervisor.onConfigurationChanged(mTempConfig);
mActivityStartController = new ActivityStartController(this);
mRecentTasks = createRecentTasks();
mStackSupervisor.setRecentTasks(mRecentTasks);
mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
mLifecycleManager = new ClientLifecycleManager();
mProcessCpuThread = new Thread("CpuTracker")
//...
}
private void start() {
removeAllProcessGroups();
mProcessCpuThread.start();
mBatteryStatsService.publish();
mAppOpsService.publish(mContext);
Slog.d("AppOps", "AppOpsService published");
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
// Wait for the synchronized block started in mProcessCpuThread,
// so that any other acccess to mProcessCpuTracker from main thread
// will be blocked during mProcessCpuTracker initialization.
try {
mProcessCpuInitLatch.await();
} catch (InterruptedException e) {
Slog.wtf(TAG, "Interrupted wait during start", e);
Thread.currentThread().interrupt();
throw new IllegalStateException("Interrupted wait during start");
}
}
代码很长,我只截取了一部分。
在构造函数中,主要初始化了一些对象,比如Context、ActivityThrad、Handler、CPU监控线程
,还有一些后文要用到的ActivityStackSupervisor、ActivityStarter
等对象,
在start
方法中,主要就是启动了CPU监控线程,然后注册了电池状态服务和权限管理服务。
AMS被启动之后,还会在SystemServer
启动三大服务的时候偷偷干一些工作,我们搜索下mActivityManagerService
变量就可以看到:
private void startBootstrapServices() {
//1、初始化电源管理器
mActivityManagerService.initPowerManagement();
//2、为系统进程设置应用程序实例并启动。
mActivityManagerService.setSystemProcess();
}
private void startCoreServices() {
// 启动UsageStatsManager,用于查询应用的使用情况
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
traceEnd();
}
private void startOtherServices() {
//安装系统的Providers
mActivityManagerService.installSystemProviders();
//启动WMS,并为AMS设置WMS关系
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
mActivityManagerService.setWindowManager(wm);
//...
}
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
}
}
其中第二步setSystemProcess
方法中,会注册AMS到ServiceManager
中,这样后续如果需要用到AMS的时候就可以通过ServiceManager
进行获取,下面马上就要讲到。
启动就说这么多,都是比较枯燥的内容,所以也没有深入下去,有个印象就行,以后如果需要用到相关知识就知道去哪里找了。
为了了解AMS的具体工作,我们就从Activity
的启动过程看起。
上文app启动流程中说过,startActivityForResult
方法会转到mInstrumentation.execStartActivity
方法:
//mInstrumentation.execStartActivity
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
可以看到,最终要拿到AMS的IBinder
类型引用,这里的ServiceManager.getService(Context.ACTIVITY_SERVICE)
是不是有点熟悉,没错,就是刚才专门调用了setSystemProcess
方法对AMS进行了注册在ServiceManager中。然后我们要使用相关服务的方法的时候,就通过Servermanager拿到对应服务的引用。
这里也就是拿到了IActivityManager
对象,IActivityManager其实就是AMS在当前进程的代理,这里的逻辑就是通过AIDL做了一个进程间的通信。因为这些服务,包括我们今天说的AMS都是在SystemServer进程中的,而我们实际用到的时候是在我们自己的应用进程中,所以就涉及到进程间通信了,这里是用的Binder机制进行通信。
Binder,ServiceManager
,这是Binder通信一整套流程,不光是AMS,包括其他的WMS等服务基本上都是通过Binder机制进行进程间通信的,具体内容可以期待下后面说到的Binder章节。
接着看启动流程,通过Binder调用到了AMS的startActivity
方法,然后会调用到ActivityStarter
的startActivity方法,在这个方法中,我们发现一个新的类:
//ActivityStarter.java
private int startActivity(...){
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
//...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
这个类翻译过来是Activity
的记录,所以猜测是和Activity有关,我们点进去看看它里面包含了什么:
final ActivityManagerService service; // owner
final IApplicationToken.Stub appToken; // window manager token
final ActivityInfo info; // all about me
ApplicationInfo appInfo; // information about activity's app
final int userId; // Which user is this running for?
final String packageName; // the package implementing intent's component
final String processName; // process where this component wants to run
final String taskAffinity; // as per ActivityInfo.taskAffinity
private int icon; // resource identifier of activity's icon.
private int logo; // resource identifier of activity's logo.
private int theme; // resource identifier of activity's theme.
int launchMode; // the launch mode activity attribute.
我保留了一些比较常用的属性,大家应该都看得出来是什么了吧,比如当前Activity的主题——theme
,当前Activity的token——apptoken
,当前Activity的包名——packageName
。
所以这个ActivityRecord
其实就是保存记录了Activity的所有信息。
接着看流程,后续会执行到startActivityUnchecked
方法,这个方法中,我们又可以看到一个新的类——TaskRecord.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
}
// 新建一个任务栈
private void setTaskToCurrentTopOrCreateNewTask() {
//...
final ActivityRecord prev = mTargetStack.getTopActivity();
final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
mTargetStack.positionChildWindowContainerAtTop(task);
}
//添加Ac到栈顶
private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
parent.addActivityToTop(mStartActivity);
} else {
mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
}
}
从代码中可知,当我们启动的Activity
需要一个新的任务栈的时候(比如启动模式为FLAG_ACTIVITY_NEW_TASK),我们会走到setTaskToCurrentTopOrCreateNewTask
方法中,新建一个TaskRecord类,并且把当前的Activity通过addActivityToTop
方法添加到栈顶。
所以这个TaskRecord
类就是一个任务栈类了,它的作用就是维护栈内的所有Activity,进去看看这个类有哪些变量:
final int taskId; // Unique identifier for this task.
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
/** Current stack. Setter must always be used to update the value. */
private ActivityStack mStack;
这里截取了一些,可以发现有任务id——taskId,任务栈的所有ActivityRecord——mActivities
,以及这个还不知道是什么的但是我知道是用来管理所有Activity和任务栈的大管家——ActivityStack。
启动流程再往后面走,就会走到的ActivityStackSupervisor
的resumeFocusedStackTopActivityLocked
方法:
//ActivityStackSupervisor.java
/** The stack containing the launcher app. Assumed to always be attached to
* Display.DEFAULT_DISPLAY. */
ActivityStack mHomeStack;
/** The stack currently receiving input or launching the next activity. */
ActivityStack mFocusedStack;
/** If this is the same as mFocusedStack then the activity on the top of the focused stack has
* been resumed. If stacks are changing position this will hold the old stack until the new
* stack becomes resumed after which it will be set to mFocusedStack. */
private ActivityStack mLastFocusedStack;
public ActivityStackSupervisor(ActivityManagerService service, Looper looper) {
mService = service;
mLooper = looper;
mHandler = new ActivityStackSupervisorHandler(looper);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
ActivityStackSupervisor
是一个管理ActivityStack
的类,在AMS的构造方法中被创建,这个类中可以看到有一些任务栈,比如mHomeStack
——包含了Launcher APP的Activity。
然后再看看ActivityStack这个大管家家里存储了什么好东西:
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
ActivityRecord mPausingActivity = null;
ActivityRecord mLastPausedActivity = null;
可以看到,在ActivityStack中:
ActivityState
,存储了Activity的所有状态。mTaskHistory
——没有被销毁的任务栈列表,mLRUActivities——通过LRU计算的列表头目是最近最少使用的Activity的ActivityRecord列表。ActivityRecord
,比如正在暂停的Activity,上一个暂停过的Activity。最后,启动流程会走到AMS的startProcessLocked
方法,然后跟Zygote进程通信,fork进程。后续就不说了。
到此,AMS中重要的三个组件我们都接触过了,分别是:
ActivityRecord
。TaskRecord
.ActivityStack
。再来画个图总结下:
其实AMS里面的逻辑还有很多很多,不仅是Activity,还有其他三大组件的一些启动调度流程都是通过AMS完成的,还有Activity任务栈相关的内容(包括taskAffinity、allowTaskReparenting),后续具体涉及到的时候会再细谈。
拜拜啦?
《Android进阶解密》 https://juejin.cn/post/6916039838470766606
感谢大家的阅读,有一起学习的小伙伴可以关注下公众号—
码上积木
❤️ 每日三问知识点/面试题,积少成多。