Android U 多任务启动分屏——整体流程介绍

2024-08-29 16:44

本文主要是介绍Android U 多任务启动分屏——整体流程介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原生的分屏功能是在多任务中,点击应用图标选择分屏,在选择多任务中的其他应用进行分屏
在这里插入图片描述

整体流程

层级结构

#1 DefaultTaskDisplayArea type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 Task=3 type=standard mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 Task=4 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,1498][1440,2960] bounds=[0,1498][1440,2960]#0 Task=55 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]#0 ActivityRecord{c8a85d8 u0 com.android.dialer/.main.impl.MainActivity t55} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]#0 17b29c2 com.android.dialer/com.android.dialer.main.impl.MainActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]#0 Task=5 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,0][1440,1463] bounds=[0,0][1440,1463]#0 Task=61 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,1463]#0 ActivityRecord{a029103 u0 com.android.messaging/.ui.conversationlist.ConversationListActivity t61} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,1463]#0 d3dd038 com.android.messaging/com.android.messaging.ui.conversationlist.ConversationListActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,1463]

对应如下树状图
在这里插入图片描述

各模块责任与堆栈

Launcher

1.确定分屏上部分,做好相关显示动画,等待选择下分屏

Launcher: 	at com.android.quickstep.views.RecentsView.createInitialSplitSelectAnimation(RecentsView.java:3196)
Launcher: 	at com.android.quickstep.views.RecentsView.createTaskDismissAnimation(RecentsView.java:3493)
Launcher: 	at com.android.quickstep.views.RecentsView.createSplitSelectInitAnimation(RecentsView.java:4636)
Launcher: 	at com.android.launcher3.uioverrides.RecentsViewStateController.handleSplitSelectionState(RecentsViewStateController.java:139)
Launcher: 	at com.android.launcher3.uioverrides.RecentsViewStateController.setStateWithAnimationInternal(RecentsViewStateController.java:109)
Launcher: 	at com.android.launcher3.uioverrides.BaseRecentsViewStateController.setStateWithAnimation(BaseRecentsViewStateController.java:91)
Launcher: 	at com.android.launcher3.uioverrides.BaseRecentsViewStateController.setStateWithAnimation(BaseRecentsViewStateController.java:61)
Launcher: 	at com.android.launcher3.statemanager.StateManager.createAnimationToNewWorkspaceInternal(StateManager.java:350)
Launcher: 	at com.android.launcher3.statemanager.StateManager.goToStateAnimated(StateManager.java:285)
Launcher: 	at com.android.launcher3.statemanager.StateManager.goToState(StateManager.java:273)
Launcher: 	at com.android.launcher3.statemanager.StateManager.goToState(StateManager.java:152)
Launcher: 	at com.android.launcher3.statemanager.StateManager.goToState(StateManager.java:145)
Launcher: 	at com.android.quickstep.views.LauncherRecentsView.initiateSplitSelect(LauncherRecentsView.java:210)
Launcher: 	at com.android.quickstep.views.TaskView.initiateSplitSelect(TaskView.java:1767)
Launcher: 	at com.android.quickstep.TaskShortcutFactory$SplitSelectSystemShortcut.onClick(TaskShortcutFactory.java:124)
Launcher: 	at com.android.quickstep.views.TaskMenuView$$ExternalSyntheticLambda3.onClick(Unknown Source:2)
Launcher: 	at android.view.View.performClick(View.java:7659)
Launcher: 	at android.view.View.performClickInternal(View.java:7636)
Launcher: 	at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
Launcher: 	at android.view.View$PerformClick.run(View.java:30156)
Launcher: 	at android.os.Handler.handleCallback(Handler.java:958)
Launcher: 	at android.os.Handler.dispatchMessage(Handler.java:99)
Launcher: 	at android.os.Looper.loopOnce(Looper.java:205)
Launcher: 	at android.os.Looper.loop(Looper.java:294)
Launcher: 	at android.app.ActivityThread.main(ActivityThread.java:8177)
Launcher: 	at java.lang.reflect.Method.invoke(Native Method)
Launcher: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
Launcher: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

2.确定选择下分屏,播放相关动画,调用SytemUI接口进入到真正分屏

Launcher: 	at com.android.quickstep.views.RecentsView.confirmSplitSelect(RecentsView.java:4716)
Launcher: 	at com.android.quickstep.views.TaskView.confirmSecondSplitSelectApp(TaskView.java:762)
Launcher: 	at com.android.quickstep.views.TaskView.onClick(TaskView.java:746)
Launcher: 	at com.android.quickstep.views.TaskView.$r8$lambda$2dErZAYzRAWboZR0vn31kIz_HGY(Unknown Source:0)
Launcher: 	at com.android.quickstep.views.TaskView$$ExternalSyntheticLambda2.onClick(Unknown Source:2)
Launcher: 	at android.view.View.performClick(View.java:7659)
Launcher: 	at android.view.View.performClickInternal(View.java:7636)
Launcher: 	at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
Launcher: 	at android.view.View$PerformClick.run(View.java:30156)
Launcher: 	at android.os.Handler.handleCallback(Handler.java:958)
Launcher: 	at android.os.Handler.dispatchMessage(Handler.java:99)
Launcher: 	at android.os.Looper.loopOnce(Looper.java:205)
Launcher: 	at android.os.Looper.loop(Looper.java:294)
Launcher: 	at android.app.ActivityThread.main(ActivityThread.java:8177)
Launcher: 	at java.lang.reflect.Method.invoke(Native Method)
Launcher: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
Launcher: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
pendingAnimation.addEndListener(aBoolean -> {mSplitSelectStateController.launchSplitTasks(aBoolean1 -> RecentsView.this.resetFromSplitSelectionState());InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);});
Launcher: 	at com.android.quickstep.util.SplitSelectStateController.launchTasksRefactored(SplitSelectStateController.java:412)
Launcher: 	at com.android.quickstep.util.SplitSelectStateController.launchTasks(SplitSelectStateController.java:329)
Launcher: 	at com.android.quickstep.util.SplitSelectStateController.launchSplitTasks(SplitSelectStateController.java:258)
Launcher: 	at com.android.quickstep.views.RecentsView.lambda$confirmSplitSelect$34(RecentsView.java:4718)
Launcher: 	at com.android.quickstep.views.RecentsView.$r8$lambda$uSHMT-0i9azkpL6YW9McOOFyjVQ(Unknown Source:0)
Launcher: 	at com.android.quickstep.views.RecentsView$$ExternalSyntheticLambda26.accept(Unknown Source:4)
Launcher: 	at com.android.launcher3.anim.AnimatorListeners$EndStateCallbackWrapper.onAnimationEnd(AnimatorListeners.java:80)
Launcher: 	at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:711)
Launcher: 	at android.animation.Animator$AnimatorCaller$$ExternalSyntheticLambda1.call(Unknown Source:4)
Launcher: 	at android.animation.Animator.callOnList(Animator.java:669)
Launcher: 	at android.animation.Animator.notifyListeners(Animator.java:608)
Launcher: 	at android.animation.Animator.notifyEndListeners(Animator.java:633)
Launcher: 	at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1306)
Launcher: 	at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1566)
Launcher: 	at android.animation.ValueAnimator.pulseAnimationFrame(ValueAnimator.java:1582)
Launcher: 	at android.animation.AnimatorSet.pulseFrame(AnimatorSet.java:1314)
Launcher: 	at android.animation.AnimatorSet.handleAnimationEvents(AnimatorSet.java:1297)
Launcher: 	at android.animation.AnimatorSet.doAnimationFrame(AnimatorSet.java:1197)
Launcher: 	at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:328)
Launcher: 	at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
Launcher: 	at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:86)
Launcher: 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1337)
Launcher: 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
Launcher: 	at android.view.Choreographer.doCallbacks(Choreographer.java:952)
Launcher: 	at android.view.Choreographer.doFrame(Choreographer.java:878)
Launcher: 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
Launcher: 	at android.os.Handler.handleCallback(Handler.java:958)
Launcher: 	at android.os.Handler.dispatchMessage(Handler.java:99)
Launcher: 	at android.os.Looper.loopOnce(Looper.java:205)
Launcher: 	at android.os.Looper.loop(Looper.java:294)
Launcher: 	at android.app.ActivityThread.main(ActivityThread.java:8177)
Launcher: 	at java.lang.reflect.Method.invoke(Native Method)
Launcher: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
Launcher: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

SystemUiProxy调用ISplitScreen.aidl进行跨进程通信到SystemUI进程
在这里插入图片描述

SytemUI

SplitScreenController实现了ISplitScreen.aidl
在这里插入图片描述

SplitScreen: 	at android.window.WindowOrganizer.startNewTransition(WindowOrganizer.java:94)
SplitScreen: 	at com.android.wm.shell.transition.Transitions.startTransition(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:1121)
SplitScreen: 	at com.android.wm.shell.splitscreen.SplitScreenTransitions.startEnterTransition(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:345)
SplitScreen: 	at com.android.wm.shell.splitscreen.StageCoordinator.startWithTask(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:701)
SplitScreen: 	at com.android.wm.shell.splitscreen.StageCoordinator.startTasks(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:623)
SplitScreen: 	at com.android.wm.shell.splitscreen.SplitScreenController$ISplitScreenImpl.lambda$startTasks$11(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:1157)
SplitScreen: 	at com.android.wm.shell.splitscreen.SplitScreenController$ISplitScreenImpl.$r8$lambda$UuHBVv3bzz4CDOdyAqlv4kaRHgY(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:0)
SplitScreen: 	at com.android.wm.shell.splitscreen.SplitScreenController$ISplitScreenImpl$$ExternalSyntheticLambda14.accept(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:0)
SplitScreen: 	at com.android.wm.shell.common.ExecutorUtils.lambda$executeRemoteCallWithTaskPermission$1(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:60)
SplitScreen: 	at com.android.wm.shell.common.ExecutorUtils.$r8$lambda$s8eUOdyrqpqzzyFwAMGxO-MaCg4(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:0)
SplitScreen: 	at com.android.wm.shell.common.ExecutorUtils$$ExternalSyntheticLambda1.run(go/retraceme d8ee0e3eecdad3cdc77c111ff5591ebe26372c47d62ba59187c5ecf96366b561:0)
SplitScreen: 	at android.os.Handler.handleCallback(Handler.java:958)
SplitScreen: 	at android.os.Handler.dispatchMessage(Handler.java:99)
SplitScreen: 	at android.os.Looper.loopOnce(Looper.java:205)
SplitScreen: 	at android.os.Looper.loop(Looper.java:294)
SplitScreen: 	at android.os.HandlerThread.run(HandlerThread.java:67)

1.对上分屏的Task进行启动

2.设置好对应的bound到configration中

3.对分屏的RootTask进行排位到最顶部

4.对下分屏的Task进行启动

对Task的操作均会保存到WindowContainerTransaction对象中,最后通过WindowOrganizer调用IWindowOrganizerController.aidl进行跨进程通信到SystemServer进程进程Task操作
在这里插入图片描述

注:SplitLayout初始化分屏的分割线的布局的流程,从代码上看,如果shell动画开关是打开的,那么该流程在1和2之间执行;反之,则会在4之后,即窗口relayout流程中通过shell动画流程调用。

SystemServer

在这里插入图片描述

WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:597)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:484)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:502)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.lambda$startTransition$3(WindowOrganizerController.java:314)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.$r8$lambda$v_6sOG-rerjgO2wQxXrUcgpnWaU(WindowOrganizerController.java:0)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController$$ExternalSyntheticLambda3.onCollectStarted(R8$$SyntheticClass:0)
WindowOrganizerController: 	at com.android.server.wm.TransitionController.startCollectOrQueue(TransitionController.java:1306)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.startTransition(WindowOrganizerController.java:310)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.startNewTransition(WindowOrganizerController.java:271)
WindowOrganizerController: 	at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:245)
WindowOrganizerController: 	at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:188)
WindowOrganizerController: 	at android.os.Binder.execTransactInternal(Binder.java:1344)
WindowOrganizerController: 	at android.os.Binder.execTransact(Binder.java:1275)

WindowOrganizerController实现了IWindowOrganizerController.aidl
其接收SystemUI中的命令来对Task进行不同的操作
applyTransaction中对Task区域大小bounds变化以及RootTask的reorder和startTask等操作进行了处理

交互简图

在这里插入图片描述

这篇关于Android U 多任务启动分屏——整体流程介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118409

相关文章

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

JAVA SE包装类和泛型详细介绍及说明方法

《JAVASE包装类和泛型详细介绍及说明方法》:本文主要介绍JAVASE包装类和泛型的相关资料,包括基本数据类型与包装类的对应关系,以及装箱和拆箱的概念,并重点讲解了自动装箱和自动拆箱的机制,文... 目录1. 包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱1.3 自动装箱和自动拆箱2. 泛型2

在VSCode中本地运行DeepSeek的流程步骤

《在VSCode中本地运行DeepSeek的流程步骤》本文详细介绍了如何在本地VSCode中安装和配置Ollama和CodeGPT,以使用DeepSeek进行AI编码辅助,无需依赖云服务,需要的朋友可... 目录步骤 1:在 VSCode 中安装 Ollama 和 CodeGPT安装Ollama下载Olla

linux环境openssl、openssh升级流程

《linux环境openssl、openssh升级流程》该文章详细介绍了在Ubuntu22.04系统上升级OpenSSL和OpenSSH的方法,首先,升级OpenSSL的步骤包括下载最新版本、安装编译... 目录一.升级openssl1.官网下载最新版openssl2.安装编译环境3.下载后解压安装4.备份

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Nginx启动失败:端口80被占用问题的解决方案

《Nginx启动失败:端口80被占用问题的解决方案》在Linux服务器上部署Nginx时,可能会遇到Nginx启动失败的情况,尤其是错误提示bind()to0.0.0.0:80failed,这种问题通... 目录引言问题描述问题分析解决方案1. 检查占用端口 80 的进程使用 netstat 命令使用 ss

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后