AMS 是 Android 中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在 Android 中非常重要。
AMS 家族
之所以称为 AMS 家族,因为会有一些类来帮助 AMS 完成相关逻辑。
Android 7.0 和 Android 8.0 对于 AMS 相关部分处理有较大的区别。
Android 7.0 的 AMS 家族 ActivityManager 是一个和 AMS 相关联的类,它主要对运行中的 Activity 进行管理,这些管理工作实际是交由 AMS 来处理的。
ActivityManager 中的方法会通过 ActivityManagerNative(以后简称 AMN)的 getDefault 方法来得到 ActivityManagerProxy(以后简称 AMP),通过 AMP 就可以和 AMN 进行通信,而 AMN 是一个抽象类,它将功能交由它的子类 AMS 来处理,因此,AMP 就是 AMS 的代理类。
AMS 作为系统服务,很多 API 是不会暴露给 ActivityManager 的,因此 ActivityManager 并不算是 AMS 家族的一份子。
接下来以 Android 7.0 的 Activity 启动过程来举例,在 Activity 的启动过程中会调用 Instrumentation 的 execStartActivity 方法。Instrumentation.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public ActivityResult execStartActivity ( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null , requestCode, 0 , null , options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException ("Failure from system" , e); } return null ; }
首先查看 AMN 的 getDefault 方法。ActivityManagerNative.java
1 2 3 4 static public IActivityManager getDefault () { return gDefault.get(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private static final Singleton<IActivityManager> gDefault = new Singleton <IActivityManager>() { protected IActivityManager create () { IBinder b = ServiceManager.getService("activity" ); if (false ) { Log.v("ActivityManager" , "default service binder = " + b); } IActivityManager am = asInterface(b); if (false ) { Log.v("ActivityManager" , "default service = " + am); } return am; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 static public IActivityManager asInterface (IBinder obj) { if (obj == null ) { return null ; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null ) { return in; } return new ActivityManagerProxy (obj); }
1 2 3 4 5 6 7 8 9 10 11 12 class ActivityManagerProxy implements IActivityManager { public ActivityManagerProxy (IBinder remote) { mRemote = remote; } ... }
再回到 Instrumentation 的 execStartActivity 方法,查看 AMP 的 startActivity(),AMP 是 AMN 的内部类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public int startActivity (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {... data.writeInt(requestCode); data.writeInt(startFlags); ... mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0 ); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override public boolean onTransact (int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case START_ACTIVITY_TRANSACTION: { ... int result = startActivity(app, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options); reply.writeNoException(); reply.writeInt(result); return true ; } ... }
AMS 的 startActivity 方法最后会返回 startActivityAsUser 方法。ActivityManagerService.java
1 2 3 4 5 6 7 8 @Override public final int startActivity (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); }
startActivityAsUser 方法最后会返回 ActivityStarter 的 startActivityMayWait 方法,这一调用过程已经脱离了 AMS 家族的范畴。
1 2 3 4 5 6 7 8 9 10 11 @Override public final int startActivityAsUser (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { enforceNotIsolatedCaller("startActivity" ); userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, false , ALLOW_FULL_ONLY, "startActivity" , null ); return mActivityStarter.startActivityMayWait(caller, -1 , callingPackage, intent, resolvedType, null , null , resultTo, resultWho, requestCode, startFlags, profilerInfo, null , null , bOptions, false , userId, null , null ); }
总结:
在 Activity 的启动过程中,提到了 AMP、AMN 和 AMS,它们共同组成了 AMS 家族的主要部分。
AMP 是 AMN 的内部类,它们都实现了 IActivityManager 接口,这样它们就可以实现代理模式,具体来讲是远程代理:
AMP 和 AMN 是运行在两个进程中的,AMP 是 Client 端,AMN 是 Server 端,而 Server 端中具体的功能都是由 AMN 的子类 AMS 来实现的,因此,AMP 就是 AMS 在 Client 端的代理类。
AMN 又实现了 Binder 类,这样 AMP 和 AMS 就可以通过 Binder 来进行进程间通信。
ActivityManager 通过 AMN 的 getDefault 方法得到 AMP,通过 AMP 就可以和 AMS 进行通信。
除了 ActivityManager 以外,有些想要与 AMS 进行通信的类也需要通过 AMP。
Android 8.0 的 AMS 家族 接下来以 Android 8.0 版本的 Activity 启动过程来展示 AMS 家族与 Android 7.0 都有哪些不同。
在 Activity 的启动过程中会调用 Instrumentation 的 execStartActivity 方法。Instrumentation.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public ActivityResult execStartActivity ( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); 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); } catch (RemoteException e) { throw new RuntimeException ("Failure from system" , e); } return null ; }
ActivityManager 的 getService 方法。ActivityManager.java
1 2 3 4 public static IActivityManager getService () { return IActivityManagerSingleton.get(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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; } };
总结:
对比 Android 7.0 的 AMS 家族,Android 8.0 的 AMS 家族要简单得多,ActivityManager 的 getService 方法会得到 IActivityManager,AMS 只需要继承 IActivityManager.Stub 类,就可以和 ActivityManager 实现进程间通信了。
AMS 的启动过程
AMS 的启动是在 SystemServer 进程中启动的。接下来从 SystemServer 的 main 方法开始:SystemServer.java
1 2 3 4 public static void main (String[] args) { new SystemServer ().run(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 private void run () { try { ... Looper.prepareMainLooper(); System.loadLibrary("android_servers" ); performPendingShutdown(); createSystemContext(); mSystemServiceManager = new SystemServiceManager (mSystemContext); mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); SystemServerInitThreadPool.get(); } finally { traceEnd(); } try { traceBeginAndSlog("StartServices" ); startBootstrapServices(); startCoreServices(); startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System" , "******************************************" ); Slog.e("System" , "************ Failure starting system services" , ex); throw ex; } finally { traceEnd(); } ... Looper.loop(); throw new RuntimeException ("Main thread loop unexpectedly exited" ); }
接下来查看引导服务 AMS 是如何启动的,startBootstrapServices 方法如下。
1 2 3 4 5 6 7 8 9 10 11 private void startBootstrapServices () { ... traceBeginAndSlog("StartActivityManager" ); mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); traceEnd(); ... }
调用了 SystemServiceManager 的 startService 方法,该方法的参数是 ActivityManagerService.Lifecycle.class。SystemServiceManager.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void startService (@NonNull final SystemService service) { mServices.add(service); long time = System.currentTimeMillis(); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException ("Failed to start service " + service.getClass().getName() + ": onStart threw an exception" , ex); } warnIfTooLong(System.currentTimeMillis() - time, service, "onStart" ); }
接下来查看 ActivityManagerService 的 Lifecycle 类。ActivityManagerService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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(); } public ActivityManagerService getService () { return mService; } }
AMS 与应用程序进程
在 Zygote 的 Java 框架层中,会创建一个 Server 端的 Socket 用来等待 AMS 请求 Zygote 来创建新的应用程序进程。要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经存在。在启动应用程序时 AMS 会检查这个应用程序所需要的应用程序进程是否存在,不存在就会请求 Zygote 进程创建需要的应用程序进程。接下来以 Service 的启动过程为例,来分析 AMS 与应用程序进程的关系。
Service 在启动过程中会调用 ActivityServices 的 bringUpServiceLocked 方法。ActiveServices.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 private String bringUpServiceLocked (ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { ... final String procName = r.processName; String hostingType = "service" ; ProcessRecord app; if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false ); if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); if (app != null && app.thread != null ) { try { app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); realStartServiceLocked(r, app, execInFg); return null ; } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } } } else { app = r.isolatedProc; if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingType = "webview_service" ; } } if (app == null && !permissionsReviewRequired) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true , intentFlags, hostingType, r.name, false , isolated, false )) == null ) { 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; } } if (!mPendingServices.contains(r)) { mPendingServices.add(r); } if (r.delayedStop) { r.delayedStop = false ; if (r.startRequested) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Applying delayed stop (in bring up): " + r); stopServiceLocked(r); } } return null ; }
总结:AMS 与应用程序进程的关系主要有以下两点:
启动应用程序时 AMS 会检查这个应用程序需要的应用程序进程是否存在。
如果需要的应用程序进程不存在,AMS 就会请求 Zygote 进程创建需要的应用程序进程。
AMS 重要的数据结构
AMS 涉及了很多数据结构,接下来分析一下 ActivityRecord、TaskRecord 和 ActivityStack,它们和应用开发关联较大,是 Activity 任务栈模型的基础。
解析 ActivityRecord 用来描述一个 Activity,内部记录了 Activity 的所有信息,是在启动 Activity 时被创建,具体是在 ActivityStarter 的 startActivity 方法中被创建的。
ActivityRecord 内部存储了 Activity 的所有信息,包括 AMS 的引用、AndroidManifes 节点信息、Activity 状态、Activity 资源信息和 Activity 进程相关信息等,需要注意的是其中含有该 ActivityRecord 所在的 TaskRecord,这就将 ActivityRecord 和 TaskRecord 关联在一起,它们是 Activity 任务栈模型的重要成员。
解析 TaskRecord 用来描述一个 Activity 任务栈。TaskRecord 的部分重要成员变量如下:
名称
类型
说明
taskId
int
任务栈的唯一标识符
affinity
String
任务栈的倾向性
intent
Intent
启动这个任务栈的 Intent
mActivities
ArrayList<ActivityRecord>
按照历史顺序排列的 Activity 记录
mStack
ActivityStack
当前属性的 ActivityStack
mService
ActivityManagerService
AMS 的作用
TaskRecord 内部存储了任务栈的所有信息,需要注意的是其中含有 ActivityStack,也就是当前 Activity 任务栈所归属的 ActivityStack。
解析 ActivityStack 一个用来管理系统所有 Activity 的管理类,其内部维护了 Activity 的所有状态、特殊状态的 Activity 以及和 Activity 相关的列表等数据。由 ActivityStackSupervisor(在 AMS 的构造方法中被创建)来进行管理。ActivityManagerService.java
1 2 3 4 5 6 public ActivityManagerService (Context systemContext) { ... mStackSupervisor = createStackSupervisor(); ... }
1 2 3 protected ActivityStackSupervisor createStackSupervisor () { return new ActivityStackSupervisor (this , mHandler.getLooper()); }
ActivityStack 的实例类型 :
在 ActivityStackSupervisor 中有多种 ActivityStack 实例,并且提供了获取它们的 get 方法。ActivityStackSupervisor.java
1 2 3 4 5 6 7 8 9 10 public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener { ... ActivityStack mHomeStack; ActivityStack mFocusedStack; private ActivityStack mLastFocusedStack; ... }
ActivityState :
在 ActivityState 中通过枚举存储了 Activity 的所有的状态,通过名称便可知道它们所代表的意义。ActivityStack.java
1 2 3 4 5 6 7 8 9 10 11 enum ActivityState { INITIALIZING, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED, FINISHING, DESTROYING, DESTROYED }
应用 ActivityState 的场景会有很多,比如:ActivityManagerService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Override 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) { mWindowManager.overridePendingAppTransition(packageName, enterAnim, exitAnim, null ); } Binder.restoreCallingIdentity(origId); } }
特殊状态的 Activity :
在 ActivityStack 中定义了一些特殊状态的 Activity,这些特殊的状态都是 ActivityRecord 类型的,ActivityRecord 用来记录一个 Activity 的所有信息。如下所示:ActivityStack.java
1 2 3 4 5 6 7 8 9 10 ActivityRecord mPausingActivity = null ;ActivityRecord mLastPausedActivity = null ;ActivityRecord mLastNoHistoryActivity = null ;ActivityRecord mResumedActivity = null ;ActivityRecord mTranslucentActivityWaiting = null ;
维护的 ArrayList :
在 ActivityStack 中维护了很多 ArrayList,它们中的元素类型主要有 ActivityRecord 和 TaskRecord。ArrayList 中的元素类型及其说明如下:
ArrayList
元素类型
说明
mTaskHistory
TaskRecord
所有没有被销毁的 Activity 任务栈
mLRUActivities
ActivityRecord
正在运行的 Activity,列表中的第一个条目是最近最少使用的 Activity
mNoAnimActivities
ActivityRecord
不考虑转换动画的 Activity
mValidateAppTokens
TaskGroup
用于与窗口管理器验证应用令牌
ActivityStack 维护了元素类型为 TaskRecord 的列表,这样 ActivityStack 和 TaskRecord 就有了关联,Activity 任务栈存储在 ActivityStack 中。
Activity 栈管理
Activity 是放入在 Activity 任务栈中的,有了任务栈,系统和开发者就能够更好地应用和管理 Activity,来完成各种业务逻辑。
Activity 任务栈模型 Activity 任务栈是由多种数据结构共同组合而成的,上面提到的 ActivityRecord、TaskRecord 和 ActivityStack 就是 Activity 任务栈模型的重要组成部分。
ActivityRecord 用来记录一个 Activity 的所有信息,TaskRecord 中包含了一个或多个 ActivityRecord,TaskRecord 用来表示 Activity 的任务栈,用来管理栈中的 ActivityRecord,ActivityStack 又包含了一个或多个 TaskRecord,它是 TaskRecord 的管理者。
Activity 栈管理就是建立在 Activity 任务栈模型之上的,有了栈管理,可以对应用程序进行操作,应用可以复用自身应用中以及其他应用的 Activity,节省了资源。比如使用一款社交应用,这个应用的联系人详情界面提供了联系人的邮箱,当点击邮箱时会跳到发送邮件的界面。
社交应用和系统 E-mail 中的 Activity 是处于不同应用程序进程的,而有了栈管理,就可以把发送邮件界面放到社交应用中详情界面所在栈的栈顶,来做到跨进程操作。为了更灵活地进行栈管理,Android 系统提供了很多配置,包括 Launch Mode、Intent 的 FLAG 和 taskAffinity 等。
备注
注:基于 Android 8.0 版本源码分析
参考资料: Android 进阶解密
单词音标: