有这里Task的概念是什么?
官方定义:“A task (from the activity that started it to the next task activity)defines an atomic group of activities that the user can move to.”。
简单来讲:Task是为了完成一个功能的一系列相关的有序Activity集合,可以理解为用户与App之间对于特定功能的一次会话。一个Task中的Activity可以来自不同的App,比如在邮件App中需要看图片附件,然后会开imageview的Activity来显示它。
am stack create <TASK_ID> <RELATIVE_STACK_BOX_ID> <POSITION> <WEIGHT>
注解如下:
am stack create: create a new stack relative to an existing one.
<TASK_ID>: the task to populate the new stack with. Must exist.
<RELATIVE_STACK_BOX_ID>: existing stack box's id.
<POSITION>: 0: before <RELATIVE_STACK_BOX_ID>
1: after <RELATIVE_STACK_BOX_ID>
2: to left of <RELATIVE_STACK_BOX_ID>
3: to right of <RELATIVE_STACK_BOX_ID>
4: above <RELATIVE_STACK_BOX_ID>
5: below <RELATIVE_STACK_BOX_ID>
<WEIGHT>: float between0.2and0.8 inclusive.\n" +
试一下:
NetEasedeMac-Pro-8:~ netease$ adb shell am stack create3140.7
createStack returned new stackId=2
/**
* Create a new TaskStack relative to a specified one by splitting the StackBox containing
* the specified TaskStack into two children. The size and position each of the new StackBoxes
* is determined by the passed parameters.
* @param stackId The id of the new TaskStack to create.
* @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to.
* @param position One of the static TASK_STACK_GOES_xxx positions defined inthisclass.
* @param weight The percentage size of the parent StackBox to devote to the new TaskStack.
* @return The new TaskStack.
*/
TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) {
if (mStackBoxId != relativeStackBoxId) {
// This isnot the targeted StackBox.
if (mStack != null) {
returnnull;
}
// Propagate the split to see if the targeted StackBox isin either sub box.
TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight);
if (stack != null) {
return stack;
}
return mSecond.split(stackId, relativeStackBoxId, position, weight);
}
// Found it!
TaskStack stack = new TaskStack(mService, stackId, mDisplayContent);
TaskStack firstStack;
TaskStack secondStack;
if (position == TASK_STACK_GOES_BEFORE) {
//TODO: Test Configuration here for LTR/RTL.
position = TASK_STACK_TO_LEFT_OF;
} elseif (position == TASK_STACK_GOES_AFTER) {
//TODO: Test Configuration here for LTR/RTL.
position = TASK_STACK_TO_RIGHT_OF;
}
switch (position) {
default:
caseTASK_STACK_TO_LEFT_OF:
caseTASK_STACK_TO_RIGHT_OF:
mVertical = false;
if (position == TASK_STACK_TO_LEFT_OF) {
mWeight = weight;
firstStack = stack;
secondStack = mStack;
} else {
mWeight = 1.0f - weight;
firstStack = mStack;
secondStack = stack;
}
break;
caseTASK_STACK_GOES_ABOVE:
caseTASK_STACK_GOES_BELOW:
mVertical = true;
if (position == TASK_STACK_GOES_ABOVE) {
mWeight = weight;
firstStack = stack;
secondStack = mStack;
} else {
mWeight = 1.0f - weight;
firstStack = mStack;
secondStack = stack;
}
break;
}
mFirst = new StackBox(mService, mDisplayContent, this);
firstStack.mStackBox = mFirst;
mFirst.mStack = firstStack;
mSecond = new StackBox(mService, mDisplayContent, this);
secondStack.mStackBox = mSecond;
mSecond.mStack = secondStack;
mStack = null;
return stack;
}
/** The stack containing the launcher app */private ActivityStack mHomeStack;
/** All the non-launcher stacks */private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
注解: move < TASK_ID> from its current stack to the top (true) or bottom (false) of < STACK_ID>.
由参数及注解可以看出,该命令不是单一的删除一个task,而是把一个task remove to a pointed stack。
实现:
Am.runStackMoveTask()->Ams.moveTaskToStack(int taskId, int stackId, boolean toTop)->ActivityStackSupervisor.moveTaskToStack(int taskId, int stackId, boolean toTop)
ActivityStackSupervisor.moveTaskToStack
void moveTaskToStack(int taskId, int stackId, boolean toTop) {
final TaskRecord task = anyTaskForIdLocked(taskId);
if (task == null) {
return;
}
final ActivityStack stack = getStack(stackId);
if (stack == null) {
Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
return;
}
removeTask(task);
stack.addTask(task, toTop);
mWindowManager.addTask(taskId, stackId, toTop);
resumeTopActivitiesLocked();
}
void removeTask(TaskRecord task) {
mWindowManager.removeTask(task.taskId);
final ActivityStack stack= task.stack;
final ActivityRecord r =stack.mResumedActivity;
if (r !=null&& r.task == task) {
stack.mResumedActivity =null;
}
if (stack.removeTask(task) &&!stack.isHomeStack()) {
if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack "+stack);
mStacks.remove(stack);
final int stackId =stack.mStackId;
final int nextStackId = mWindowManager.removeStack(stackId);
// TODO: Perhaps we need to let the ActivityManager determine the next focus...if (mFocusedStack ==null|| mFocusedStack.mStackId == stackId) {
// If this is the last app stack, set mFocusedStack to null.
mFocusedStack = nextStackId == HOME_STACK_ID ?null : getStack(nextStackId);
}
}
}