Android 7.0 和 Android 8.0 对于 AMS 相关部分处理有较大的区别
Android 7.0 的 AMS 家族
主要有三个类
以 Android 7.0 的 Activity 启动过程来举例,在 Activity 的启动过程中会调用 Instrumentation 的 execStartActivity 方法
/*frameworks/base/core/java/android/app/Instrumentation.java*/
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options){
...
//调用 AMN 的 getDefault 来获取 AMS 的代理类 AMP,接着调用 AMP 的 startActivity 方法
int result = ActivityManagerNative.getDefault().startActivity(...);
...
}
/*ActivityManagerNative.java*/
static public IActivityManager getDefault(){
return gDefault.get();
}
private static final Singleton<IActivityManager> getDefault = new Singleton<IActivityManager>(){
protected IActivityManager create(){
//得到名为 "activity" 的 Service 引用,也就是 IBinder 类型的 AMS 的引用
IBinder b = ServiceManager.getService("activity");
...
//将该 Service 引用封装成 AMP 类型对象,并将它保存到 gDefault 中,此后调用 AMN 的 getDefault 方法就会直接获得 AMS 的代理对象 AMP
IActivityManager am = asInterface(b);
}
}
static public IActivityManager asInterface(IBinder obj){
if(obj == null){
return null;
}
//descriptor 值为 android.app.IActivityManager; 该处代码主要用来查询本地进程是否有 IActivityManager 接口实现,如果有则返回
IActivityManager in = (IActivityManager) obj.queryLocalInterface(descriptor);
if(in != null){
return in;
}
//如果没有就将IBinder类型的 AMS 引用封装成 AMP
return new ActivityManagerProxy(obj);
}
class ActivityManagerProxy implements IActivityManager{
//在构造方法中将 AMS 的引用赋值给变量 mRemote,这样在 AMP 中就可以使用 AMS 了
public ActivityManagerProxy(IBinder remote){
mReomte = remote;
}
}
//再回到 Instrumentation 的 execStartActivity 方法,来看看 AMP 的 startActivity 方法。AMP 是 AMN 的内部类
/*ActivityManagerNative.java*/
public int startActivity(...) throws RemoteException{
...
//将传入的参数写入到 Parcel 类型的 data 中
data.writeInt(requestCode);
data.writeInt(startFlags);
...
//通过 IBinder 类型对象 mRemote (AMS的引用) 向服务器端的 AMS 发送一个 START_ACTIVITY_TRANSACTION 类型的进程间通信请求。那么服务器端 AMS 就会从 Binder 线程池中读取客户端发来的数据,最终调用 AMN 的 onTransact 方法
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException{
switch(code){
case START_ACTIVITY_TRANSACTION:
...
int result = startActivity(aap, callingPackage, intetn, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
}
//在 onTransact 方法中会调用 AMS 的 startActivity 方法
/*ActivityManagerService.java*/
public final int startActivity(IApplicationThread caller, ....){
return startActivityAsUser(...);
}
//该方法中最后会调用到 ActivityStarter 的 startActivityMayWait 方法
public final int startActivityAsUser(...,int userId){
...
return mActivityStarter.startActivityMayWait(...);
}
Android 8.0 的 AMS 家族
同样以 Activity 启动过程来举例,Android 8.0,在 Activity 的启动过程中会调用 Instrumentation 的 execStartActivity 方法
/*frameworks/base/core/java/android/app/Instrumentation.java*/
public ActivityResult execStartActivity(Context who, ...){
...
int result = ActivityManager.getService().startActivity(...);
...
}
/* ActivityManager 的 getService 方法
* ActivityManager.java
*/
public static IActivityManager getService(){
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>(){
@Override
protected IActivityManager create(){
//得到名为 "activity" 的 Service 引用(Context.ACTIVITY_SERVICE的值为“activity”),也就是 IBinder 类型的 AMS 的引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 将它转换成 IActivityManager 类型的对象,
final IActivityManager am = IActivityManager.Stub.asInterface(b);
}
}
IActivityManager.java 类是由 AIDL 工具在编译时自动生成的,IActivityManager.aidl 的文件路径为 framework/base/core/java/android/app/IActivityManager.aidl。要实现进程间通信,服务器端也就是AMS只需要继承 IActivityManager.Stub 类并实现相应的方法就可以了。采用 AIDL 后就不需要使用 AMS 的代理类 AMP 了
AMS 的启动过程
AMS 的启动是在 SystemServer 进程中启动的,我们从 SystemServer 的 main 方法
/*framworks/base/services/java/com/android/server/SystemServer.java*/
public static void main(String[] args){
new SystemServer().run();
}
private void run(){
try{
...
//创建消息Looper
Looper.prepareMainLooper();
//加载动态库 libandroid_servers.so
System.loadLibrary("android_servers");
//创建 SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
//启动引导服务。用 SystemServiceManager 启动 AMS、PowerManagerService、PackageManagerService等服务
startBootstrapServices();
//启动核心服务。启动 DropBoxManagerService、BatteryService、UsageStatusService 和 WebViewUpdateService
startCoreServices();
//启动其他服务。启动 CameraService、AlarmManagerService、VrManagerService等服务
startOtherServices();
}
}
//接下来我们主要查看引导服务,AMS是如何启动的。也就是 startBootstrapServices()方法
private void startBootstrapServices(){
...
traceBeginAndSlog("StartActivityManager");
//调用 SystemServiceManager 的 startService 方法
mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
...
}
/*SystemServiceManager.java*/
public void startService(final SystemService service){
//将 service 对象添加到 ArrayList 类型的 mServices 中来完成注册
mServices.add(service);
//调用 service 的 onStart 方法来启动 service 对象
service.onStart();
}
/** 这个 service 对象具体指的是什么呢?
* ActivityManagerService.Lifecycle.class 是 AMS 的内部类
* ActivityManagerService.java
*/
public static final class Lifecycle extends SystemService{
private final ActivityManagerService mService;
public Lifecycle(Context context){
super(context);
//在 Lifecycle 的构造方法中创建 AMS 实例
mService = new ActivityManagerService(context);
}
@Override
public void onStart(){
//当调用 SystemService 类型的 service 的 onStart 方法时,实际上是调用了该处 AMS 的 start 方法
mService.start()
}
//返回 AMS 实例,调用该方法实际上得到的就是 AMS 实例
public ActivityManagerService getService(){
return mService;
}
}
AMS 与应用程序进程
在第二章系统启动中将到了 Zygote 的 java 框架层中,会创建一个 Server 端的 Socket,这个 Socket 用来等待 AMS 请求 Zygote 来创建新的应用程序进程。
要启动一个应用程序,首先要保证这个应用程序所需要的程序进程已经存在。在启动应用程序时 AMS 会检查这个应用程序需要的进程是否存在,不存在就会请求 Zygote 进程创建需要的应用程序进程
这里以 Service 的启动过程为例,来分析 AMS 与应用程序进程的关系。Service 在启动过程中会调用 ActiveServices 的 bringUpServiceLocked 方法
/*frameworks/base/services/core/java/com/android/server/am/ActiveServices.java*/
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException{
...
//得到 ServiceRecord 的 processName 的值并赋值给 procName,processName 用来描述 Service 想要在哪个进程运行,默认是当前进程,我们可以在 AndroidManifest文件中设置 android:process 属性来开启一个新进程运行 Service
final String procName = r.processName;
...
//查询是否存在一个与 Service 对应的 ProcessRecord 类型的对象 app
ProcessRecord app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
//判断用来运行 Service 的应用进程是否存在
if(app != null && app.thread != null){
//启动 Service
realStartServiceLocked(r, app, execInFg);
}
//如果用来运行 Service 的应用程序进程不存在
if(app == null && !permissionReviewRequired){
//使用 startProcessLocked() 方法创建对应的应用程序进程
if((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, hostingType, r.name, false, isolated, false)) == null)
}
}
AMS 与应用程序进程的关系主要有以下两点:
AMS 重要的数据结构
ActivityRecord
ActivityRecord 内部记录了 Activity 的所有信息,因此用来描述一个 Activity,它是在启动 Activity 时被创建的,具体是在 ActivityStarter 的 startActivity 方法中被创建的
ActivityRecord 的部分重要的成员变量如下表所示
名称 | 类型 | 说明 |
---|
service | ActivityManagerService | AMS 的引用 | info | ActivityInfo | Activity中代码和AndroidManifest设置的节点信息,比如 launchMode | launchedFromPackage | String | 启动 Activity 的包名 | taskAffinity | String | Activity 希望归属的栈 | task | TaskRecord | ActivityRecord 所在的 TaskRecord | app | ProcessRecord | ActivityRecord 所在的应用程序进程 | state | ActivityState | 当前 Activity 的状态 | icon | int | Activity 的图标资源标识符 | theme | int | Activity 的主题资源标识符 |
TaskRecord
TaskRecord 用来描述一个 Activity 任务栈,内部存储了任务栈的所有信息,其中含有 ActivityStack,也就是当前 Activity 任务栈所归属的 ActivityStack
名称 | 类型 | 说明 |
---|
taskId | int | 任务栈的唯一标识符 | affinity | String | 任务栈的倾向性 | intent | Intent | 启动这个任务栈的Intent | mActivities | ArrayList<ActivityRecord> | 按照历史顺序排列的 Activity 记录 | mStack | ActivityStack | 当前归属的 ActivityStack | mService | ActivityManagerService | AMS的引用 |
ActivityStack 是一个管理类,用来管理系统所有 Activity,其内部维护了 Activity 的所有状态、特殊状态的 Activity 以及和 Activity 相关的列表等数据。ActivityStack 是由 ActivityStackSupervisor 来进行管理的
taskAffinity
我们可以在 AndroidManifest.xml 中设置 android:taskAffinity,用来指定 Activity 希望归属的栈,在默认情况下,同一个应用程序的所有的 Activity 都有着相投的 taskAffinity
taskAffinity 在下面两种情况时会产生效果:
-
taskAffinity 与 FLAG_ACTIVITY_NEW_TASK 或者 singleTask 配合。如果新启动 Activity 的 taskAffinity 和栈的 taskAffinity 相同则加入到该栈中;如果不同,就会创建新栈 -
taskAffinity 与 allowTaskReparenting 配合。如果 allowTaskReparenting 为 true,说明 Activity 具有转移的能力
|