Android8.0多窗口调研

Android Nougat多窗口简析 Android从7.0开始支持多窗口,官方终于支持这一功能了。其实很多ODM厂商早已实现该功能,实现方式各种各样,最通用的方案是多Stack方案,比较痛苦的是每次版本升级都要花很大力气进行适配和解各种乱七八糟的bug,现在终于一统江湖了,并且第三方应用开始对多窗口进行适配兼容。 阅读详情

Android8.0多窗口调研

一、概述

Android8.0上面原生的多窗口功能支持四种模式:全屏、分屏、画中画、FreeForm模式。多窗口主要涉及ActivityManagerService、WindowManagerService、Input三个模块。以下分析基于Android8.0代码。

二、原理框架

Android原生多窗口是多Stack方案,即存在多个ActivityStack。ActivityStack是一个抽象的栈,每个栈都有自己的屏幕区域bound和id,Activity是以Task方式组织并放在某一个Stack中的。比如,Launcher、Recents属于id=HOME_STACK的栈中。8.0主要涉及以下:

HOME_STACK_ID、FULLSCREEN_WORKSPACE_STACK_ID、FREEFORM_WORKSPACE_STACK_ID、DOCKED_STACK_ID、PINNED_STACK_ID、RECENTS_STACK_ID、ASSISTANT_STACK_ID

AMS和WMS中对Stack分别用ActivityStack和TaskTack描述,通过StackId来映射。对Task分别用TaskRecord、Task描述,通过TaskId来映射。

每个Activity显示在所属ActivityStack的bound区域内,多个Activity显示在各自ActivityStack的bound区域内,这样就可以实现多窗口。但是FreeForm模式下,Activity的bound由所属Task决定,而非Stack。多窗口不仅仅是控制Activity放入不同ActivityStack中,同时还要改变Activity的生命周期,即FocusActivity是resume状态,其他可见Activity是Pause状态,并不会进入Stop状态。

整个系统中只会有一个FocusStack,一个FocusActivity。用户在哪个Activity中操作,FocusActivity便指向该Activity,FocusStack便指向FocusActivity所属的Stack。注意,画中画模式下,浮层Activity无法成为FocusActivity,故浮层属于的Stack并非FocusStack。

进入/退出多窗口按以下逻辑框架顺序进行处理:

step1.调整ActivityStack栈

step2.调整Task栈

step3.调整Activity堆栈,调整WMS中APPWindowToken堆栈

step4.调用Activity生命周期函数

step5.添加Window到WMS

step6.过度动画及应用窗口显示

三、关键函数

移栈:

AMS.moveTaskToStack()

AMS.moveTaskToDockedStack()

AMS.moveTopActivityToPinnedStack()

分屏相互切换:

AMS.swapDockedAndFullscreenStack()

真正切换task(重点):

TaskRecord.reparent()//8.0新增分屏task移动都在此函数执行

调整栈大小:

AMS.resizeDockedStack()

AMS.resizePinnedStack()

ActivityStackSupervisor.resizeStackUncheckedLocked()

Activity生命周期:

ActivityStack.resumeTopActivityInnerLocked():

Activity启动:

ActivityStarter.startActivityUnchecked()

四、多窗口变更通知和查询

Activity.isInMultiWindowMode()调用该方法以确认 Activity是否处于多窗口模式。 Activity.isInPictureInPictureMode()调用该方法以确认 Activity是否处于画中画模式。 Activity.onMultiWindowModeChanged() Activity 进入或退出多窗口模式时系统将调用此方法。在Activity 进入多窗口模式时,系统向该方法传递true 值,在退出多窗口模式时,则传递false 值。 Activity.onPictureInPictureModeChanged() Activity 进入或退出画中画模式时系统将调用此方法。在Activity 进入画中画模式时,系统向该方法传递true 值,在退出画中画模式时,则传递false 值。每个方法还有 Fragment版本,例如  Fragment.isInMultiWindowMode()。

五、源码分析

1、分屏模式

进入分屏有两种入口:

AMS.startActivityFromRecents()//在任务栏中拖动一个分屏应用到顶部

AMS.moveTaskToDockedStack()//长按底部任务按键

简单分析下AMS.startActivityFromRecents():

进入分屏之前PhoneActivity属于id=1(FullScreenStack),任务栏Recents属于id=0(HomeStack),FocusStack指向HomeStack。进入分屏相当于启动PhoneActivity,并将其放到上半区域Stack中,上半区域为DockedStack(id=3),即将PhoneActivity从id=1(FullScreenStack)移到id=3的DockedStack中,最后将HomeStack的boundresize,处在下半屏。注意分屏后FocusStack指向上半区域DockedStack。整个时序如下所示。



AMS.moveTaskToDockedStack():

在支持分屏应用界面长按底部任务按键,进入分屏模式。相当于把PhoneActivity从id=1移到id=3的DockedStack中,同时resizeHomeStack。类似前者,不做详细分析。

2、画中画模式

画中画即置顶Activity,Activity的窗口永远位于所有窗口之上,所属的Stack自然位于所有Stack的上面,这类特殊的Stack称为PinnedStack(id=4)。PinnedStack无法成为FocusStack,Activity也无法成为FocusActivity。

如何启动画中画,只需在AndroidManifest中声明Activity时添加android:supportsPictureInPicture="true"和android:resizeableActivity="true”属性,并调用新方法 Activity.enterPictureInPictureMode()。时序图如下:




ps:reparent没做详细展出

PinnedStack为非Focusablestack,Activity为非focusactivity,resumeFocusedStackTopActivityLocked()只会将stack堆栈中FocusStack的focusactivity进行resume,其他任何activity均为paused或stoped状态,所以画中画Activity是处于paused状态的.

3、FreeForm模式

FreeForm模式下并不存在与之对应的多个Stack,而是只有一个FreeFormStack(stackId=2)存放了多个Task。这种模式下决定Activity显示位置的不是Stackbound,而是Taskbound,即每个Task都有自己的bound。

FreeForm模式下Activity从Recents中启动,调用的接口为AMS.startActivityFromRecents(),其时序跟从任务栏拖动一个应用进入分屏差不多,只是此处Activity在FreeFormStack中启动,其他基本流程基本一致,不再详细分析。

4、窗口resize/拖动

在分屏模式下,拖动中间bar条改变分屏大小,中间bar条是SystemUI添加到系统一个名为“DockedStackDivider”的浮窗,接收触摸事件,根据MotionEvent的Y值动态调用ActivityManagerService.resizeDockedStack()来改变DockedStack的bound大小,完成窗口大小调整。

在FreeForm模式下的窗口缩放和拖拽跟分屏模式不一样,没有SystemUI添加的bar浮窗,但是在FreeForm模式下DecorView与子ContentView间插入了一个DecorCaptionView,代码如下所示。


//FreeForm模式下config发生改变,会触发onConfigurationChanged,调用到此处

窗口调整跟拖拽便是在DecorCaptionView中根据触摸事件检测开启的,调用的开启函数便是WindowManagerService.startMovingTask(IWindowwindow, float startX, float startY)。就拿拖拽来说,用户按住FreeFormActivity的窗口边缘然后移动,此拖动过程分为三步:

 step1.DecorCaptionView检测触摸事件,发现是拖拽或窗口调整,那么跨进程调用WindowManagerService.startMovingTask()开启Task移动;

 step2.WMS.startMovingTask()会创建一个TaskPositioner,TaskPositioner会注册一个InputChannel到InputManager中,此后的触摸事件便会发送到TaskPositioner中来;

  step3.TaskPositioner接收move事件,计算WindowRect然后调用AMS.resizeTask(inttaskId, Rect bounds, int resizeMode)来更新Activity窗口bound。

六、区别OS

os的多窗口使用的也是类似多stack方案,通过调整stack大小,同时显示多个应用。

和原生的区别在于,os在切换窗口大小的时候需要加载不同的布局,系统强制发送onConfigurationChanged给应用,应用根据config加载不同布局。原生在config变化会销毁activity,然后根据新config重新启动新页面。os修改系统逻辑不重启应用。

七、总结

Android8.0针对多窗口进一步完善,并且将taskRecord相关的切换放到reparent新方法中统一处理。os的方案在8.0上面需要针对新特新重新修改。




Android开发工程师核心技能与面试全攻略 移动应用开发中,Android系统作为全球占有率最高的移动操作系统,其开发技术栈持续演进。从基础的Java/Kotlin语言特性到Android四大组件原理,开发者需要建立完整的知识体系。现代Android开发更涉及Jetpack组件库、Compose声明式UI等前沿技术,性能优化与架构设计能力成为区分工程师水平的关键指标。在工程实践中,内存泄漏排查、启动速度优化等场景考验开发者的实战能力。对于求职者而言,掌握Handler机制、Binder IPC等系统原理,以及具备模块化架构设计经验,是通过大厂技术面试 阅读详情

相关推荐

Quest 2 VR浏览器实战:WebXR网页空间化改造指南

VR浏览器并非简单将网页3D化,而是基于WebXR标准重构人机交互范式——通过空间坐标系映射、注视驱动与手势绑定,实现网页元素在三维空间中的物理化定位与操作。其技术核心在于XRReferenceSpace、XRInputSource等API对传统CSS transform和事件模型的升维替代,带来显著的注意力聚焦优化与操作效率提升。在Oculus Quest 2等移动VR设备上,轻量级WebXR适配(如空间分层、注视滚动、手势缩放)即可使技术文档类网页单次阅读时长提升37%,跳出率下降52%。本文聚焦真实工

weixin_34384557的博客 406

基于Android T代码分析: 在freeform窗口的标题栏拖动时移动窗口流程和拖动freeform窗口边沿改变大小流程

基于Android T代码分析: 在freeform窗口的标题栏拖动时移动窗口流程和拖动freeform窗口边沿改变大小流程

月山知了的博客 3741

android自由窗口freeform模式的实现

freeform模式默认关闭,一些手机厂商开启了此功能,模拟器没有开启。 adb shell settings put global enable_freeform_support 1 adb shell settings put global force_resizable_activities 1 Intent intent = new Intent(MainActivity.this, FreeFormActivity.class); i

分享技术与经验的博客 1万+

android9duochuangkoubiji

一、概述: AndroidQ上面原生的多窗口功能支持四种模式:全屏、分屏、画中画、FreeForm模式。 多窗口主要涉及ActivityManagerService、WindowManagerService、Input三个模块。/// 二、原理框架 Android原生多窗口是多Stack方案,即存在多个ActivityStack。ActivityStack是一个抽象的栈,每个栈都有自己的屏...

cengdong的博客 890

【源码剖析】Launcher 8.0 源码 (6) --- Launcher 启动流程 第二步之启动流程中的分屏简介

启动流程第二步,对于分屏状态的判断。分屏状态是在当前手机有两个及以上的支持分屏功能的应用在前后台运行的时候长按recent按钮,而出现手机屏幕一分为二,可以同时有两个应用在前台运行和显示的功能。   第二步源码如下: if (isInMultiWindowModeCompat()) {     Display display = getWindowManager().getDefaultDi...

dax120的博客 770

Android 12之启动画面Splash Screens(二) -- framework原理

本篇介绍Splash Screens的framework层原理。

分享技术与经验的博客 6521

Android 原生 多屏显示 (分屏) 原理 解析

发快递就拉上几个

Jon.Lo 的专栏 1万+

安卓开发总监实战指南:从团队搭建到项目交付

本文深入剖析安卓开发总监的核心职责,包括团队搭建、技术规划、难点攻克和质量把控。重点解析从0到1组建团队的方法论,涵盖招聘策略、开发规范制定和敏捷管理;详细阐述平板/笔电业务线的技术选型与架构设计;针对性能优化、兼容性等核心技术难点提供解决方案;并分享项目全生命周期的质量管理体系。文章结合真实案例和量化指标(如崩溃率<0.1%),最后附上面试问题库,涵盖行为、技术、情景三类问题及参考答案,为技术管理者提供实用指南。

郑伟强dev的专栏 217

Android——事件拦截机制分析

我们设计的场景实例是(你所在的公司):一个总经理——MyViewGroupA,最外层的ViewGroup一个部长——MyViewGroupA,中间的ViewGroup一个干活的你——MyView,在最底层本实例的整个布局结构图:对于Viewgroup来说,需要重写如下所示的三个方法 @Override public boolean dispatchTouchEvent(MotionE...

qq_32329745的博客 242

从0开始学GEE python——Google Earth Engine (GEE) 和 geemap 库来获取 Sentinel-2 卫星影像,并将其可视化

这段代码的目的是从 Sentinel-2 卫星影像中获取特定地点的影像,并将其可视化在地图上。通过设置合适的波段和可视化参数,用户可以清晰地查看该地区的卫星影像。

此星光明博客 1167

保姆级教程:用Python+OpenCV实现相移法与格雷码三维重建(从生成条纹到点云生成)

本文详细介绍了使用Python和OpenCV实现相移法与格雷码三维重建的全流程,从条纹生成到点云计算。通过结构光技术,结合相移法和格雷码,实现高精度的三维重建,适用于无纹理物体表面的密集对应点生成。教程包含环境搭建、条纹生成、相位计算、三维点云重建及常见问题排查,适合计算机视觉开发者和研究人员。

weixin_33443333的博客 350

新版负一屏变天了!分享pixel新桌面负一屏技术调研报告

Pixel Launcher 的负一屏不是在 Launcher 进程内嵌入一个 View 或 Fragment,而是利用 Android 12+ 的,在 Launcher 的 Task 内创建一个独立的,将 Google App (Velvet) 的以模式嵌入其中。两个 Activity 拥有各自独立的 Window 和 Surface偏移目标机制层级View 层负一屏 (MinusOneActivity)Surface 层。

learnframework的博客 403

M1/M2 Mac用户看过来:不装VirtualBox,用PD虚拟机也能跑ENSP的保姆级教程

本文为M1/M2 Mac用户提供了一份不依赖VirtualBox,使用Parallels Desktop虚拟机运行ENSP的详细指南。通过ARM架构的Win10镜像选择、组件替代方案和网络配置优化,实现ENSP核心功能的高效运行,特别适合网络工程师在苹果芯片设备上进行网络模拟。

weixin_28683065的博客 411

2026安卓平板选购指南:从场景驱动到硬件确定性的理性决策框架

安卓平板已超越‘iOS替代品’的初级定位,成为基于开放生态、USB OTG原生支持和Linux内核可扩展性的生产力载体。其技术原理根植于对HID协议、动态刷新率调度、ADC压感采样及VC均热板等底层硬件的深度调优;核心价值在于将系统自由度转化为真实场景效能——如教育场景的手写延迟<25ms、创作者所需的Delta E<1.5色准、银发族依赖的语音唤醒率>99%。典型应用场景涵盖网课批注、跨屏协同办公、户外绘画、轻量视频剪辑与长时差旅娱乐。本文聚焦2026年真实可用的安卓平板体验,结合手写笔压感线性度、屏幕D

weixin_34387468的博客 2万+

OpenHarmony自定义Launcher

OpenHarmony源码版本:4.0release开发板:DAYU / rk3568DevEco Studio版本:4.0.0.600切换分支为OpenHarmony-4.0-Release,并下载源码。

Abner_Crazy的博客 1630

15、基于最优传输的协作多视图聚类框架

本文提出了一种基于最优传输理论的协作多视图聚类框架,通过引入协作学习机制在不同视图间建立先验交互,以提升共识聚类的质量。框架包含两种新方法:协作共识投影方法(CoCP)和基于新表示的协作共识方法(CoCNR)。CoCP在全局空间中整合多视图信息并进行共识投影,而CoCNR则通过协作编码生成新的数据表示以实现更优聚类。方法利用熵正则化的Wasserstein距离与Wasserstein重心,有效捕捉数据分布间的几何结构,并通过聚合步骤获得统一模型。实验结果表明,所提方法在多个数据集上均优于现有方法,具有良好的

gpt4scribbler的博客 85

Hanime1Plugin:Android平台动漫流畅观看解决方案

移动互联网时代,动漫内容消费呈现爆发式增长,但Android平台的观看体验仍存在显著痛点。根据第三方调研数据显示,83%的用户在观看过程中遭遇过广告干扰,72%的用户经历过因网络波动导致的播放中断,而68%的用户表示曾因操作复杂放弃使用特定应用。这些痛点形成了完整的体验障碍链:广告打断沉浸式体验→网络不稳定导致观看中断→复杂操作增加使用门槛,最终导致用户留存率降低和内容消费意愿下降。 ## 核心

gitblog_00001的博客 8059

基于YOLOv11的气象目标检测系统:台风眼与钩状回波检测

气象目标检测是计算机视觉在气象领域的重要应用,对台风预警和强对流天气监测具有重要意义。本文详细介绍了一种基于YOLOv11的气象目标检测系统,能够有效识别卫星云图中的台风眼和雷达图中的钩状回波。系统包含完整的数据处理流程、模型训练策略以及用户友好的Web界面。我们使用了公开的气象数据集进行训练和验证,并提供了完整的实现代码。实验结果表明,本系统在气象目标检测任务中达到了较高的准确率和实用性。关键词:气象目标检测;YOLOv11;台风眼检测;钩状回波;深度学习;计算机视觉台风眼检测数据集。

YOLO 474

跳出娱乐打办公,华为MatePad Pro走了一着妙棋

11月25日,华为在上海发布了Mate家族的新产品华为MatePad Pro。当前,网上关于华为 MatePad Pro的评论很多,有说它对标苹果iPad系列,也有人说它是华为在安卓平板的新尝试。 玺哥也说说自己的看法。 华为MatePad Pro欲改变人们对平板的认知 自2010年苹果ipad发布以来,这种定位于智能手机和笔记本电脑产品之间的产品凭借漂亮的外 形,简单的交互而备受消费者喜爱。 i...

hexi008的博客 768

详解【异质图卷积网络 RGCN】回顾:图神经网络问题的三大处理步骤 | 从起源说起,RGCN核心公式解释,两种降低模型参数量/优化的方式,附核心代码实现讲解

本篇,我们深入分析和学习RGCN的原理以及为何要这么做。首先让我们来回顾对于图神经网络问题的三大处理步骤,可以说,这是该深度学习模型的基本理解,后续都是在深化其中的细节处理。然后以容易理解的方式,引出异质图卷积网络RGCN的由来,主要讲解其核心公式和论文中作者所提出的两种降低模型参数量/优化的处理办法,并给出基础分解以及块对角分解的核心实现代码讲解。最后附上RGCN源代码及说明。

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 1279

量子化学仿真软件:VASP_(7).表面与界面性质模拟

在量子化学仿真软件领域,表面与界面性质的模拟是研究多相催化、表面反应、材料科学等领域的关键工具。VASP(Vienna Ab Initio Simulation Package)作为一种广泛使用的密度泛函理论(DFT)计算软件,提供了强大的功能来模拟表面与界面的性质。本节将详细介绍如何使用VASP进行表面与界面性质的模拟,包括模型构建、输入文件准备、计算设置、结果分析等步骤。

kkchenjj的博客 950

面试题kkk

这篇文章摘要主要涵盖了Android开发中的核心知识点和技术难点,包括数据结构、Java与Kotlin语言特性、多线程与并发、内存管理、安卓组件与UI、IPC通信、数据库、多媒体处理、设计模式、性能优化、跨端开发等多个方面。文章详细解析了常见数据结构的使用与实现、JVM机制、内存泄漏分析与解决方案、Activity生命周期、事件分发机制、Handler原理、音视频处理、设计模式应用等核心内容,并提供了实际项目中的技术卡点与解决方案。此外,还涉及了性能优化策略、跨端开发差异、技术方案设计思路以及Git常用命令

mix39的博客 930

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

微软PowerToys:如何通过30+智能工具实现企业工作效率翻倍?

在数字化转型浪潮中,企业面临的最大挑战之一是如何提升员工的生产力。传统的工作流程中,员工每天要花费大量时间在重复性操作上:寻找文件、调整窗口布局、转换图片格式、管理颜色代码……这些看似微小的效率损耗,累积起来却造成惊人的时间浪费和成本支出。**企业风险管理**不仅关乎财务安全,更包括运营效率的风险管控。微软PowerToys正是为解决这一痛点而生的终极解决方案——一套完整的Windows生产力工具

gitblog_00402的博客 921

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【课程设计】外卖系统-计算机毕业设计源码76911

首先,本文对外卖系统的需求进行了详细分析,明确了系统的主要功能模块,包括用户注册与登录、餐品浏览与搜索、订单管理、支付系统以及配送管理等。通过对这些功能的深入研究,确定了系统的整体架构和技术选型。 其次,基于Django框架的特点,本文详细介绍了系统的设计与实现过程。Django作为一个高效的Web框架,提供了强大的后台管理功能和灵活的数据库操作,使得系统的开发过程更加高效。本文重点阐述了模型层、视图层和模板层的设计思路,并通过具体代码示例展示了如何实现各个功能模块。

Biye_Design的博客 2026

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android播放视频几秒后,出现暂停报如下错误

Priority scheduling not supported 遇到此问题无从下手,不是程序代码的错误,也找不到具体哪行出错了。 多番尝试之后,更换视频播放的各种第三方框架依然没有解决问题。 于是新开了个activity,单独播放就没问题。这时,我就查代码看问题了,发现逻辑代码里面写了个timer定时器,几秒会调用http网络请求,而我的视频就是acitvity已进入就开始播放。于是就造成了上面的错误。 结合错误信息和分析来说:应该是视频解码的线程机制和主线程的定时任务里的网络请求机制.

ruizhenggang的博客 2585

Android8.0适配那点事(一)

1、通知渠道(Channeld)当然,适配8.0的第一步自然是把targeSdk升级到26,在8.0中所有通知的实现都需要提供通知渠道,否则,所有通知在8.0系统上面都不能正常显示;下图是8.0系统上,APP通知的展示样式: APP适配渠道通知的实现如下:2、悬浮窗8.0 API 新增了一种悬浮窗的窗口类型,TYPE_APPLICATION_OVERLAY;如果应用使用 SYSTEM_ALERT_...

qq_23392167的博客 780
上一篇: android user
下一篇: trace 重命名
stepsljz
博客等级 码龄14年 11粉丝 11原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值