Framework 学习(七)AMS 家族,kotlin 开发思维
我们知道 SystemServiceManager 的 startService 方法最终会返回 Lifecycle 类型的对象,紧接着又调用了 Lifecycle 的 getService 方法,这个方法会返回 AMS 类型的 mService 对象,见注释 3 处,这样 AMS 实例就会被创建并且返回。
继续来看看 SystemServer 中 startBootstrapServices()方法的注释 2:
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); //1
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
...
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
注释 1 中的 Context.ACTIVITY_SERVICE=“activity”,注释 1 就是把 ActivityManagerService 实例注册到 ServiceManager 中。ServiceManager 用来管理系统中的各种 Service,用系统 C/S 架构中的 Binder 机制通信,Client 端要使用某个 Service,则需要先到 ServiceManager 查询 Service 的相关信息,然后根据 Service 的相关信息与 Service 所在的 Server 进程建立通讯通路,这样 Client 端就可以使用 Service 了。
IBinder b = ServiceManager.getService("activity"); //查询
AMS 与应用进程启动
在 Framework 学习(二)Zygote 进程启动过程这篇文章中,我们说过 Zygote 进程会创建一个服务器端 Socket,并监听 Socket 来等待客户端请求创建新的应用程序进程。要启动一个应用程序,首先要保证这个应用程序的进程已经被启动。AMS 在启动应用程序时会检查这个应用程序的进程是否存在,不存在就会请求 Zygote 进程将应用程序进程启动。
在 Framework 学习(五)应用程序启动过程这篇文章,我们说过应用程序启动时会走到 ActivityStackSupervisor 的 startSpecificActivityLocked 函数启动指定的 ActivityRecored。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
ActivityStackSupervisor#startSpecificActivityLocked()
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
//1
ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig); //2
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e);
}
}
//3
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);
}
ActivityStackSupervisor#getProcessRecordLocked()
final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
if (uid == Process.SYSTEM_UID) {
// The system gets to run in any process. If there are multiple
// processes with the same uid, just pick the first (this
// should never happen).
SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
if (procs == null) return null;
...
}
...
}
注释 1 处获取当前 Activity 所在的进程的 ProcessRecord,如果进程已经启动了,会执行注释 2 处的代码。否则执行注释 3 的代码。
注释 2 处调用 realStartActivityLocked 来启动应用程序。
注释 3 处调用 AMS 的 startProcessLocked 来启动应用程序进程。关于应用程序进程的启动我们可以看 Framework 学习(六)应用程序进程启动过程这篇文章。
AMS 家族
ActivityManager 是一个和 AMS 相关联的类,它主要是对运行中的 Activity 进行管理,这些管理工作并不是由 ActivityManager 自己来处理,而是交由 AMS 来处理,ActivityManager 中的方法会通过 ActivityManagerNative(以后简称 AMN)的 getDefault 方法来得到 ActivityManagerProxy(以后简称 AMP),通过 AMP 就可以和 AMN 进行通信,而 AMN 是一个抽象类,它会将功能交由它的子类 AMS 来处理,因此,AMP 就是 AMS 的代理类。AMS 作为系统核心服务,很多 API 是不会暴露给 ActivityManager 的,因此 ActivityManager 并不算是 AMS 家族一份子。
下面以 Activity 启动的例子看一下 AMS 家族的调用。Framework 学习(五)应用程序启动过程一文中我们简单讲过 AMS 中 Binder 机制,本文我们继续总结一下。
Activity 启动过程中会调用 Instrumentation 的 execStartActivity 方法。
frameworks/base/core/java/android/app/Instrumentation.java
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);
//1
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;
}
注释 1 调用 ActivityManagerNative 的 getDefault 就是获取 AMS 的代理对象 AMP 的,接着调用它的 startActivity 方法。
frameworks/base/core/java/android/app/ActivityManagerNative.java
ActivityManagerNative.getDefault()
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity"); //1
IActivityManager am = asInterface(b); //2
return am;
}
};
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);
}
getDefault 方法调用了 gDefault 的 get 方法,gDefault 是一个 Singleton 类。注释 1 处从 ServiceManager 得到名为”activity”的 Service 代理对象,也就是 AMS 的代理对象。
注释 2 处将它封装成 AMP 类型对象,并将它保存到 gDefault 中,此后调用 AMN 的 getDefault 方法就会直接获得 AMS 的代理 AMP 对象。
ActivityManagerProxy
class ActivityManagerProxy implements IActivityManager
{
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
...
}
AMP 的构造方法中将 AMS 的引用赋值给变量 mRemote ,这样在 AMP 中就可以使用 AMS 了。
其中 IActivityManager 是一个接口,AMN 和 AMP 都实现了这个接口,用于实现代理模式和 Binder 通信。
再回到 Instrumentation 的 execStartActivity 方法,来查看 AMP 的 startActivity 方法,AMP 是 AMN 的内部类,代码如下所示。
ActivityManagerProxy#startActivity()
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 {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); //1
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
首先会将传入的参数写入到 Parcel 类型的 data 中。在注释 1 处通过 IBinder 对象 mRemote 向 AMN 发送一个 START_ACTIVITY_TRANSACTION 类型的进程间通信请求。那么服务端 AMN 就会从 Binder 线程池中读取我们客户端发来的数据,最终会调用 AMN 的 onTransact 方法中执行。
ActivityManagerNative#onTransact()
@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); //1
reply.writeNoException();
reply.writeInt(result);
return true;
}
}
因为 AMS 继承了 AMN,服务端真正的实现是在 AMS 中,注释 1 最终会调用 AMS 的 startActivity 方法。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
**ActivityManagerService#s
tartActivity()**
@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());
}
评论