如果不是跨进程,AMS和应用程序之间的调用会比较简单。但是由于AMS和应用程序之间属于不同进程,那么之间的交互是通过Binder机制来交互的。现在具体分析一下。
首先Activity与AMS交互。
Activity与AMS的交互方法我们可以从startActivity开始分析。最终会进入
int result = ActivityManagerNative.getDefault()
.startActivityAsUser(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options, user.getIdentifier());
ActivityManagerNative.getDefault 获取的是ActivityManagerProxy。
public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options,
int userId) 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);
}
data.writeInt(userId);
mRemote.transact(START_ACTIVITY_AS_USER_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
最终相应就是ActivityManagerServie了,为啥是这个呢,因为最早是这个注册到ServiceManage了。
看下响应。
这里有个ApplicationThreadNative。属于AMS持有的引用客户端。这个就是AMS远程跟Activity交互使用的。它的服务端正是ActivityThread中的 ApplicationThread。这样AMS的信息可以很方便的回调到ActivityThread主线程。注意一下,这个属于匿名的binder。还是来分析下,这两者怎么关联的吧。
case START_ACTIVITY_AS_USER_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
int userId = data.readInt();
int result = startActivityAsUser(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
reply.writeNoException();
reply.writeInt(result);
return true;
}