要想更好地理解 AMS ,很有必要了解 AMS 的启动过程, AMS 的启动是在 SystemServer进程中启动的,关于 SystemServer 进程的启动过程在“Android系统启动流程(3) —— 解析SystemServer进程启动过程”中已经讲过,这里就从 SystemServer 的 main 方法开始分析,代码如下所示:
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
在main方法中只调用了SystemService的run方法,代码如下所示:
frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
try {
...
// 创建消息Looper
Looper.prepareMainLooper();
// 加载动态库libandroid_servers.so
System.loadLibrary("android_servers"); // ... 1
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// 创建系统的Context
createSystemContext();
// 创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext); // ... 2
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// Start services.
try {
traceBeginAndSlog("StartServices");
// 启动引导服务
startBootstrapServices(); // ... 3
// 启动核心服务
startCoreServices(); // ... 4
// 启动其他服务
startOtherServices(); // ... 5
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
int uptimeMillis = (int) SystemClock.elapsedRealtime();
MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
final int MAX_UPTIME_MILLIS = 60 * 1000;
if (uptimeMillis > MAX_UPTIME_MILLIS) {
Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
"SystemServer init took too long. uptimeMillis=" + uptimeMillis);
}
}
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void startBootstrapServices() {
...
// Activity manager runs the show.
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService(); // ... 1
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
...
}
public T startService(Class serviceClass) {
try {
// 获取Lifecycle类的名字
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
// 获取Lifecycle的构造器
Constructor constructor = serviceClass.getConstructor(Context.class);
// 创建Lifecycle对象
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service); // ... 1
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
在startService方法中,通过反射的方式创建了Lifecycle类的对象,在注释1处调用
SystemServiceManager的另一个startService方法,代码如下所示:
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service); // ... 1
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart(); // ... 2
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context); // ... 1
}
@Override
public void onStart() {
mService.start(); // ... 2
}
@Override
public void onCleanupUser(int userId) {
mService.mBatteryStatsService.onCleanupUser(userId);
}
public ActivityManagerService getService() { // ... 3
return mService;
}
}
在“Android系统启动流程(2) —— 解析Zygote进程启动过程”一文中讲到了Zygote的java框架层中,会去创建一个Server端的Socket,这个Socket用来等待AMS请求Zygote来创建新的应用程序进程。要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经存在。在启动应用程序时AMS会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote进程创建需要的应用程序进程。
这里以Service的启动过程为例,来分析AMS与应用程序进程的关系。Service在启动过程中会调用ActiveService的bringUpServiceLocked方法,对Service启动流程不清楚的可以查看“解析Service的启动过程”这篇文章,代码如下所示:
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
// 获取Service想要在哪个进程中运行
final String procName = r.processName; // ... 1
String hostingType = "service";
ProcessRecord app;
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); // ... 2
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
// 如果运行Service的应用程序进程存在
if (app != null && app.thread != null) { // ... 3
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
// 启动Service
realStartServiceLocked(r, app, execInFg); // ... 4
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
} else {
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingType = "webview_service";
}
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
// 如果用来运行Service的应用程序进程不存在
if (app == null && !permissionsReviewRequired) { // ... 5
// 创建应用程序进程
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, false, isolated, false)) == null) { // ... 6
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
...
return null;
}
ActivityRecord它内部记录了Activity的所有信息,因此它用来描述一个Activity,它在启动Activity时被创建,具体是在ActivityStarter的startActivity方法中被创建的,ActivityRecord 的部分重要成员变量 如表1所示。
名称 | 类型 | 说明 |
service | ActivityManagerService | AMS的引用 |
info | AcitivityInfo | Activity中代码和AndroidManifes设置的节点信息,比如launchMode |
launchedFromPackage | String | 启动Activity的包名 |
taskAffinity | String | Activity希望归属的栈 |
task | TaskRecord | ActivityRecord所在的TaskRecord |
app | ProcessRecord | ActivityRecord所在的应用程序进程 |
state | ActivityState | 当前Activity的状态 |
icon | int | Activity的图标资源标识符 |
theme | int | Activity的主题资源标识符 |
名称 | 类型 | 说明 |
taskId | int | 任务栈的唯一标识符 |
affinity | String | 任务栈的倾向性 |
intent | Intent | 启动这个任务栈的Intent |
mActivities | ArrayList |
按照历史顺序排列的Activity记录 |
mStack | ActivityStack | 当前归属的ActivityStack |
mService | ActivityManagerService | AMS的引用 |
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public ActivityManagerService(Context systemContext) {
...
mStackSupervisor = createStackSupervisor();
...
}
protected ActivityStackSupervisor createStackSupervisor() {
return new ActivityStackSupervisor(this, mHandler.getLooper());
}
1. ActivityStack的实例类型
在ActivityStackSupervisor中有多种ActivityStack实例,代码如下所示:
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
...
/** 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;
...
}
ActivityStack getFocusedStack() {
return mFocusedStack;
}
2. ActivityState
在ActivityStack中通过枚举存储了Activity的所有状态,代码如下所示:
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}
通过名称我们可以很轻易知道这些状态所代表的意义。ActivityState的场景会有很多,比如下面的代码:
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) {
synchronized(this) {
ActivityRecord self = ActivityRecord.isInStackLocked(token);
if (self == null) {
return;
}
final long origId = Binder.clearCallingIdentity();
if (self.state == ActivityState.RESUMED
|| self.state == ActivityState.PAUSING) { // ... 1
mWindowManager.overridePendingAppTransition(packageName,
enterAnim, exitAnim, null);
}
Binder.restoreCallingIdentity(origId);
}
}
overridePendingTransition 方法用于设置 Activity 的切换动画, 在注释1处可以看到只有 ActivityState 为RESUMED 状态或 PAUSING 状态时才会调用 WMS 类型的 mWindowManager 对象的 overridePendingAppTransition 方法来切换动画。
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
/**
* When we are in the process of pausing an activity, before starting the
* next one, this variable holds the activity that is currently being paused.
*/
ActivityRecord mPausingActivity = null; // 正在暂停的Activity
/**
* This is the last activity that we put into the paused state. This is
* used to determine if we need to do an activity transition while sleeping,
* when we normally hold the top activity paused.
*/
ActivityRecord mLastPausedActivity = null; // 上一个已经暂停的Activity
/**
* Activities that specify No History must be removed once the user navigates away from them.
* If the device goes to sleep with such an activity in the paused state then we save it here
* and finish it later if another activity replaces it on wakeup.
*/
ActivityRecord mLastNoHistoryActivity = null; // 最近一次没有历史记录的Activity
/**
* Current activity that is resumed, or null if there is none.
*/
ActivityRecord mResumedActivity = null; // 已经Resume的Activity
// The topmost Activity passed to convertToTranslucent(). When non-null it means we are
// waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
// are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
// Activity in mTranslucentActivityWaiting is notified via
// Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
// background activity being drawn then the same call will be made with a true value.
ActivityRecord mTranslucentActivityWaiting = null; // 传递给convertToTranslucent方法的最上层的Activity
ArrayList | 元素类型 | 说明 |
mTaskHistory | TaskRecord | 所有没有被销毁的Activity任务栈 |
mLRUActivities | ActivityRecord | 正在运行的Activity,列表中的第一个条目是最近最少使用的Activity |
mNoAnimActivities | ActivityRecord | 不考虑转换动画的Activity |
mValidateAppTokens | TaskGroup | 用于与窗口管理器验证应用令牌 |
做过应用开发的同学都知道Activity是放入在Activity任务栈中的,有了任务栈,系统和开发者就能够更好地应用和管理Activity来完成各种业务逻辑。
1. Activity 任务栈模型
Launch Mode 用于设定Activity的启动方式,无论是哪种启动方式,所启动的Activity都会位于Activity栈的栈顶,主要有一下4中Launch Mode。
1. standerd:默认模式,每次启动Activity都会创建一个新的Activity实例。
2. singleTop:如果要启动的 Activity 已经在栈顶,则不会重新创建 Activity ,同时该 Activity 的 onNewlntent 方法会被调用。如果要启动的 Activity 不在栈顶,则会重新创建该 Activity 的实例。
3. singleTask:如果要启动的 Activity 已经存在于它想要归属的栈中,那么不会创建该 Activity 实例,将栈中位于该 Activity 之上的所有的 Activity 移除栈,同时该 Activity 的 onNewlntent 方法会被调用。如果要启动的 Activity 不存在于它想要归属的栈中,并且该栈存在,则会重新创建该 Activity 的实例。如果要启动的 Activity 想要归属的校不存在,则首先要创建一个新栈,然后创建该 Activity 实例并压入到新栈中。
4. singleInstance:和 singleTask 基本类似,不同的是启动 Activity 时,首先要创建一个新栈,然后创建该 Activity 实例并压入新栈中,新栈中只会存在这 一个 Activity 实例。
3. Intent的FLAG
在Intent 中定义了很多 FLAG ,其中有几个 FLAG 也可以设定 Activity 的启动方式,如果 Launch Mode 和 FLAG 设定的 Activity 的启动方式有冲突 ,则以 FLAG 设定的为准。
除了上述这 FLAG ,还有一些 FLAG 对我们分析栈管理有些帮助。
4. taskAffinity