分屏代码在AOSP其实老早就存在了,就一直没有开启而已,在6.0版本可以通过设置系统属性ro.build.type
改为userdebug
,并在开发者选项中开启多窗口模式
,然后在最近任务上就会个按钮可以实现分屏。
通过adb命令也可以实现分屏
$ am task resize 25 0 720 1080 1920
在最近任务的调用链
RecentsActivity#onTaskResize ->
RecentsResizeTaskDialog#placeTasks ->
SystemServicesProxy#resizeTask ->
ActivityManagerNative#resizeTask ->
ActivityManagerService#resizeTask ->
ActivityStackSupervisor#resizeStackLocked
在am的调用链
Am#runTaskResize->
ActivityManagerNative#resizeTask ->
ActivityManagerService#resizeTask ->
ActivityStackSupervisor#resizeTaskLocked
ActivityStackSupervisor的实现
foundStackWithBounds
ActivityStackSupervisor#moveTaskToStackLocked ->
ActivityStackSupervisor#resizeStackLocked
ActivityStackSupervisor#moveTaskToStackLocked - >
WindowManagerService#moveTaskToStack
ActivityStackSupervisor#resizeStackLocked ->
WindowManagerService#resizeStack
WindowManagerService的实现
WindowManagerService#resizeStack ->
TaskStack#setBounds
TaskStack#resizeWindows ->
updateLayout??
看来让人心情不好的乱七八糟源码分析
//---> frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void resizeTaskLocked(TaskRecord task, Rect bounds) {
task.mResizeable = true;
final ActivityStack currentStack = task.stack;
if (currentStack.isHomeStack()) {
// Can't move task off the home stack. Sorry!
return;
}
// 找到给定区域相同的栈
final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
if (matchingStackId != -1) {
// There is already a stack with the right bounds!
if (currentStack != null &&
currentStack.mStackId == matchingStackId) {
// Nothing to do here. Already in the right stack...
return;
}
// Move task to stack with matching bounds.
moveTaskToStackLocked(task.taskId, matchingStackId, true);
return;
}
// 栈里只有一个task,直接resize栈
if (currentStack != null && currentStack.numTasks() == 1) {
// Just resize the current stack since this is the task in it.
resizeStackLocked(currentStack.mStackId, bounds);
return;
}
// 挪动task到新的栈
// Create new stack and move the task to it.
final int displayId =
(currentStack != null && currentStack.mDisplayId != -1)
? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);
if (newStack == null) {
Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
return;
}
moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
resizeStackLocked(newStack.mStackId, bounds);
}
分屏的核心是task跟bound,需要看一下task是怎么裂变的