AMS一个很重要的系统服务,安卓的四大组件都与之关联,这里便深入了解下它。
知识点
一、AMS关联类
Android 7.0和Android 8.0对于AMS相关部分处理有较大的区别,为了更好地理解AMS家族,这里将分别介绍Android 7.0和Android 8.0的AMS关联类。
1、Android 7.0的AMS关联类
简介
- ActivityManager:主要对运行中的Activity进行管理。管理工作实际并不是由ActivityManager来处理的,而是交由AMS来处理的。
- ActivityManagerNative :简称AMN。是一个抽象类,其功能由他的子类AMS处理。其getDefault方法可得到ActivityManagerProxy(简称AMP)。ActivityManager通过AMP与AMN通信。
- ActivityManagerProxy:AMN的内部类、AMS的代理类。
- ActivityManagerService:系统服务,运行在SystemSever进程。AMS作为系统服务,很多API是不会暴露给ActivityManager的。
接下来看下AMS在安卓7.0中Activity启动过程中的使用,这里就从Activity的startActivity看起,最终会调用Instrumentation的execStartActivity
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;
}
可以看到,execStartActivity方法中会调用AMN的getDefault来获取AMS的代理类AMP。接着调用了AMP的startActivity方法,先来查看AMN的getDefault方法做了什么:
AMN 类中:
static public IActivityManager getDefault() {
//1、在getDefault方法中调用了gDefault的get方法。
return gDefault.get();
}
/*2、
gDefault是一个Singleton类
*/
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//得到Ibind 类型的AMS引用
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
// 3、将它封装成AMP类型对象,并将它保存到gDefault中,
//此后调用AMN的getDefault方法就会直接获得AMS的代理对象AMP
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
//4、descriptor值为android.app.IActivityManager类型
(IActivityManager)obj.queryLocalInterface(descriptor);
//5、查询本地进程是否有IActivityManager接口的实现,
//如果有则返回,如果没有就使用ActivityManagerProxy将IBinder类型的AMS引用封装成AMP
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
//6、在AMP的构造方法中将AMS的引用赋值给变量mRemote,这样在AMP中就可以使用AMS了。
//其中IActivityManager是一个接口,AMN和AMP都实现了这个接口,
//用于实现代理模式和Binder通信
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
再回到Instrumentation的execStartActivity方法,来查看AMP的startActivity方法,AMP是AMN的内部类
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 {
...
//private IBinder mRemote;
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
首先将传入的参数写入到Parcel类型的data中。通过IBinder类型对象mRemote(AMS的引用)向服务器端的AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务器端AMS就会从Binder线程池中读取客户端发来的数据,最终会调用AMN的onTransact方法。
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
...
// 调用AMS的start 方法
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
调用AMS的start 方法,AMS的startActivity方法最后会返回startActivityAsUser方法,等后续就是一系列无关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,如上图解。
2、Android 8.0的AMS关联类
Instrumentation#execStartActivity方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String 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, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManager#getService
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//1、获得Binder类型的AMS引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//2、将Binder类型引用转换成IActivityManager类型的对象,
//这段代码采用的是AIDL
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
采用AIDL后就不需要使用AMS的代理类AMP了,因此Android8.0去掉了AMP,代替它的是IActivityManager,它是AMS在本地的代理。
图解&小结
ActivityManager的getService方法会得到IActivityManager,AMS只需要继承IActivityManager.Stub类,就可以和ActivityManager实现进程间通信了
二、AMS的启动过程
AMS的启动是在SystemServer进程中启动的。也即AMS运行在SystemSever进程。SystemServer的main方法如下:
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
... // 创建Looper
Looper.prepareMainLooper();
// 1、加载动态库android_servers(C,C++ 文件编译产物)
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// 2、创建system service manager。对系统的服务进行创建、启动、
//生命周期管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
...
//3、分批启动系统服务
//启动引导服务
startBootstrapServices();
//启动核心服务
startCoreServices();
//启动其他服务
startOtherServices();
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
AMS服务就是在启动系统服务时启动的。
系统服务有很多的有的需要立即启动,有的不需要立即启动,所以系统就分三批启动系统服务:
- 引导服务(BootstrapServices):主要开启了ActivityManagerService、PowerManagerService、PackageManagerService等服
- 核心服务(CoreServices):主要开启了DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService等服务
- 其他服务(OtherServices):主要启动了CameraService、AlarmManagerService、VrManagerService等服务。
既然AMS的开启是SystemSever进程中调用引导服务时开启的,那么就看下startBootstrapServices方法:
private void startBootstrapServices() {
...
// 开启AMS相关的代码
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
...
}
可以发现具体是通过SystemServiceManager#startService方法传参 ActivityManagerService.Lifecycle.class来开启的。具体细节如下:
SystemServiceManager.java
public void startService(@NonNull final SystemService service) {
// 注册AMS服务,方便系统管理
mServices.add(service);
//调用AMS的start方法开启AMS服务
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");
}
调用AMS的start方法开启AMS服务
这里需要注意:
- 所有的系统服务父类都是SystemService
- ActivityManagerService.Lifecycle.class 参数:可以看出Lifecycle是AMS的内部类。其实AMS对象创建、AMS的开启、AMS对象的获取都是这个内部类提供的功能。具体如下一看便知:
public static final class Lifecycle extends SystemService {
//AMS
private final ActivityManagerService mService;
// 1、构造方法中创建AMS对象
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
// 2、AMS start方法
@Override
public void onStart() {
mService.start();
}
// 3、返回AMS对象
public ActivityManagerService getService() {
return mService;
}
}
三、AMS 与应用进程
Zygote的Java框架层中,会创建一个Server端的Socket,这个Socket用来等待AMS请求Zygote来创建新的应用程序进程。
要启动一个应用程序首先要保证应用程序的进程已经启动,否则就要先启动应用程序需要的进程,然后启动应用程序。
AMS管理着四大组件的开启以及组件信息的维护,AMS的职责是十分重要的。在启动应用程序时AMS会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote进程创建需要的应用程序进程。
这里就以startService为例子展示下:
ActiveService#bringUpServiceLocked()
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
...
//1、processName描述service想要运行的进程,默认值为当前进程
final String procName = r.processName;
String hostingType = "service";
ProcessRecord app;
if (!isolated) {
//2、mAm为AMS类型对象,这里调用AMS的getProcessRecordLocked表示去AMS中查询
//是否存在一个与service对应的ProcessRecord类型对象。
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) {//3、service应用进程存在
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//4、启动service
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;
}
}
...
return null;
}
伪代码表示
//app 对象为ProcessRecord类型,开启应用进程时AMS内部会维护记录这个进程。
if(app!=null,app.thread!=null){
开启组件
}else{
ams向zogote发socket请求创建应用进程
}
四、AMS重要的数据结构
Activty是放入在Activity任务栈中的,有了任务栈,系统和开发者就能够更好地应用和管理Activity,来完成各种业务逻辑。
Activity任务栈模型是由多种数据结构共同组合而成的:
- ActivityRecord:记录一个Activity的所有信息。
- TaskRecord:包含一个或者多个ActivityRecord,用来管理栈中的ActivityRecord。
- ActivityStack:包含一个或者多个TaskRecord,用来管理栈中的TaskRecord,也即用来管理系统所有Activity。
ActivityStack
ActivityStack是一个管理类,用来管理系统所有Activity。
1、ActivityStack何时被创建??
ActivityStack是由ActivityStackSupervisor来进行管理的,而ActivityStackSupervisor在AMS的构造方法中被创建。
ActivityStackSupervisor成员变量中维护了很多类型的ActivityStack如:
- ActivityStack mHomeStack:用来存储Launcher App的所有Activity
- ActivityStack mFocusedStack:表示当前正在接收输入或启动下一个Activity的所有Activity
通过ActivityStackSupervisor提供了获取上述ActivityStack 的方法,比如要获取mFocusedStack,只需要调用ActivityStackSupervisor的getFocusedStack方法就可以了
2、ActivityStack内部维护的数据
(1)枚举了Activity所有状态
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}
具体场景:Activity的切换动画系统源码
@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);
}
}
可以看到只有ActivityState 为RESUMED状态或者PAUSING状态时才会调用WMS类型的mWindowManager对象的overridePendingAppTransition方法来切换动画
(2)重要字段
//所有没有被销毁的Activity任务栈
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
// 正在运行的activity,列表中第一个是最近最少使用的Activity
final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
//不考虑转化动画的activity
final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>();
//正在暂停的activity
ActivityRecord mPausingActivity = null;
//上一个已经暂停的activity
ActivityRecord mLastPausedActivity = null;
...
TaskRecord相关重要字段
TaskRecord 用来描述一个Activity任务栈。TaskRecord的作用,其内部存储了任务栈的所有信息,包括任务栈的唯一标识符、任务栈的倾向性、任务栈中的Activity记录和AMS的引用等,需要注意的是其中含有ActivityStack,也就是当前Activity任务栈所归属的ActivityStack。
字段 | 说明 |
int taskId | 任务栈唯一标识符 |
String affinity | 任务倾向性 |
Intent intent | 启动任务栈的intent |
ArrayList<ActivityRecord> mActivities | 按照历史顺序排列的activity记录 |
ActivityStack mStack | 当前activity归属的任务栈 |
ActivityManagerService mService | AMS引用 |
ActivityRecord相关重要字段
用来描述一个Activity,记录了Activity的所有信息,包括AMS的引用、AndroidManifes节点信息、Activity状态、Activity资源信息和Activity进程相关信息等
需要注意的是其中含有该ActivityRecord所在的TaskRecord,这就将ActivityRecord和TaskRecord关联在一起。
具体是在启动Activity 时被创建的,具体是在ActivityStarter 的startActivity方法中被创建的。
字段 | 说明 |
ActivityManagerService service | AMS引用 |
ActivityInfo info | Activity中代码和AndroidManifes设置的节点,比如launchMode |
String launchedFromPackage | 启动activity的包名 |
String taskAffinity | Activity希望归属的栈 |
TaskRecord task | ActivityRecord所在的TaskRecord |
ProcessRecord app | ActivityRecord所在的应用程序进程 |
ActivityState state | 当前activity的状态 |
int icon | Activity的图标资源标识符 |
int theme | Activity的主题资源标识符 |
The end
参考:
安卓进阶解密:微信读书版