1.ActivityStackSupervisor
它是一个计算类,所有关于ActivityRecord,TaskRecord,ActivityStack的操作都是在这里面进行;
①来看这句代码:
ActivityRecord sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
其中,resultTo是IBinder类型,mSupervisor就是ActivityStackSupervisor,看下ActivityStackSupervisor.isInAnyStackLocked()的内部实现:
ActivityRecord isInAnyStackLocked(IBinder token) {
int numDisplays = mActivityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
//从后往前找
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
//根据传递进来的token从ActivityStack中得到ActivityRecord
final ActivityRecord r = stack.isInStackLocked(token);
if (r != null) {
return r;
}
}
}
return null;
}
ActivityDisplay是什么,它内部维护着一个ArrayList类型的mStacks,mStacks保存着所有的ActivityStack;
关于 stack.isInStackLocked(token)的代码在ActivityStack的描述里面;
2.ActivityStack
①ActivityStack中有个mTaskHistory:ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
mTaskHistory 维护着手机中所有的TaskRecorder;
②isInStackLocked函数:
ActivityRecord isInStackLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
return isInStackLocked(r);
}
点评:通过传进来的token寻找到相应的ActivityRecord;
关于ActivityRecord.forTokenLocked(token)的代码在ActivityRecord的描述里面;
3.ActivityRecorder
①ActivityRecorder保存着关于Activity的所有信息,比如TaskRecorder,ActivityStack等;
每个ActivityRecorder都有自己所属的栈TaskRecorder,ActivityRecorde被保存在TaskRecorder.mActivities中;
②forTokenLocked()函数
public static ActivityRecord forTokenLocked(IBinder token) {
try {
return Token.tokenToActivityRecordLocked((Token)token);
} catch (ClassCastException e) {
Slog.w(TAG, "Bad activity token: " + token, e);
return null;
}
}
看到这里,就得仔细地分析下了:
Token是ActivityRecord的内部类,代码如下:
static class Token extends IApplicationToken.Stub {
private final WeakReference<ActivityRecord> weakActivity;
private final String name;
Token(ActivityRecord activity, Intent intent) {
weakActivity = new WeakReference<>(activity);
name = intent.getComponent().flattenToShortString();
}
private static ActivityRecord tokenToActivityRecordLocked(Token token) {
if (token == null) {
return null;
}
ActivityRecord r = token.weakActivity.get();
if (r == null || r.getStack() == null) {
return null;
}
return r;
}
@Override
public String toString() {
.........
}
@Override
public String getName() {
return name;
}
}
可以看到,通过一个IBinder类型的token,就可以获取到相应的ActivityRecord ,那token与ActivityRecord是如何进行绑定的呢?
我们知道,在调用Activity.startActivity时会调用下面这个方法:
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this,
mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);
其中有个mToken,它的类型是IBinder;这里的这个mToken是Activity启动者的mToken,并不是被启动者的;
mToken在attach()方法中被赋值的;mToken到底是啥呢,它就是对应的是ActivityRecorder.Token;
当AMS与Activity进行绑定的时候,会创建一个Token对象,这个Token对象就包含着ActivityRecord,每一个Activity都有一个Token,所以,根据Token对象找到的ActivityRecord也是唯一的;