引言
自android7开始,分屏功能官方就已经实现了。Android11的操作方式是点击rescent键,选择一个应用进入分屏,然后系统会自动在下半屏显示另一个应用。
然后客户是客制化的系统,没有任务栏和状态栏。所以需要开发通过代码进入分屏的方式,并且客户希望可以自由开启一个应用进入上分屏或下分屏,自由退出上分屏或下分屏。这些原生Android11都是没有的,只能新开发。
新开发功能
- 从taskId进入分屏
- 启动intent进入分屏
- 从taskId退出分屏
- 自由退出分屏

分屏原理说明
首先看一个未分屏状态下的activity栈状态,执行命令
adb shell dumpsys activity activities
Task display areas in top down Z order:
TaskDisplayArea DefaultTaskDisplayArea
mLastOrientationSource=Task{
5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
mPreferredTopFocusableStack=Task{
5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
mLastFocusedStack=Task{
5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
Application tokens in top down Z order:
* Task{
5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
mLastOrientationSource=ActivityRecord{
e499cf9 u0 com.android.dialer/.main.impl.MainActivity t12}
bounds=[0,0][720,1280]
* ActivityRecord{
e499cf9 u0 com.android.dialer/.main.impl.MainActivity t12}
* Task{
d0d36ff #1 visible=true type=home mode=fullscreen translucent=false I=com.android.launcher3/.uioverrides.QuickstepLauncher U=0 StackId=1 sz=1}
mLastOrientationSource=Task{
da384a7 #10 visible=true type=home mode=fullscreen translucent=false I=com.android.launcher3/.uioverrides.QuickstepLauncher U=0 StackId=1 sz=1}
bounds=[0,0][720,1280]
* Task{
da384a7 #10 visible=true type=home mode=fullscreen translucent=false I=com.android.launcher3/.uioverrides.QuickstepLauncher U=0 StackId=1 sz=1}
mLastOrientationSource=ActivityRecord{
c16f68e u0 com.android.launcher3/.uioverrides.QuickstepLauncher t10}
bounds=[0,0][720,1280]
* ActivityRecord{
c16f68e u0 com.android.launcher3/.uioverrides.QuickstepLauncher t10}
* Task{
c140c5 #3 visible=false type=undefined mode=split-screen-primary translucent=true ?? U=0 StackId=3 sz=0}
bounds=[0,0][720,606]
* Task{
b689f28 #4 visible=false type=undefined mode=split-screen-secondary translucent=true ?? U=0 StackId=4 sz=0}
bounds=[0,626][720,1280]
看最后两个task,他们分属于不同的stackId,且都有不同的mode和bounds,mode分别是split-screen-primary和split-screen-secondary。split-screen-primary表示上半屏,且bounds=[0,0][720,606]就是处在上半屏的位置;split-screen-secondary表示下半屏,bounds=[0,626][720,1280]就是处在下半屏的位置。
Android系统其实就是根据stack来实现分屏的,系统启动之初就创建好了几个主要的stack,每个stack规定了自己的bounds和mode,bounds即大小和显示位置,mode即显示模式。Android系统中的每一个Activity都位于一个Task中,每个task都位于一个ActivityStack中。
全屏模式下大部分activity都处于fullscreen模式下的activityStack,把要分屏显示的activity的task移入分屏ActivityStack即可分屏显示。
从taskId进入分屏
原生android11只支持设置一个taskId显示在上半屏进入分屏状态,我这里实现的可以根据参数设置一个taskId进入上分屏或下分屏。
有四个方法可以实现,分别是:
1 ActivityTaskManager.setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
2 ActivityTaskManager.setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds, boolean showRecents)
3
//注:原生android11只支持进入上分屏
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(true ? WINDOWING_MODE_SPLIT_SCREEN_PRIMARY : WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
options.setSplitScreenCreateMode(true ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
ActivityTaskManager.getService().startActivityFromRecents(getTaskId(), options.toBundle())
4
//注:此方法只适合在已经分屏状态下启动activity进入下半屏
Intent intent = new Intent("android.settings.SETTINGS");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
startActivity(intent);
启动intent进入分屏
原生android11只支持在已经分屏状态下启动activity显示在另半屏,我这里实现的可以根据参数设置启动intent进入上分屏或下分屏。
Intent intent = new Intent(this, SubActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY);
intent.putExtra("showOnSpliteScreenPrimary", inflate.cbShowInSplitePrimary.isChecked());
startActivity(intent);
从taskId退出分屏
//第二个参数是WindowConfiguration.WINDOWING_MODE_FULLSCREEN
ActivityTaskManager.setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
自由退出分屏
//此功能新增的,show_splitScreenPrimary指定全屏显示上半屏幕或下半屏。
ActivityTaskManager.getService().exitSpliteScreenMode(show_splitScreenPrimary);
功能实现
上面是罗列客户端的使用接口,下面贴出修改点。
关键修改类:
frameworks/base/core/java/android/content/Intent.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
frameworks/base/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
修改如下:
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 24d59a0826c8..8fd92d171cf6 100644
--- a


2222

被折叠的 条评论
为什么被折叠?



