当前位置: 首页 > news >正文

Android14 WMS-窗口绘制之relayoutWindow流程(一)-Client端

Android14 WMS-窗口添加流程(一)-Client端-CSDN博客

Android14 WMS-窗口添加流程(二)-Server端-CSDN博客

经过上述两个流程后,窗口的信息都已经传入了WMS端。

f57b6efae369489bbf40634cccb43bf0.jpg

 

1. ViewRootImpl#setView

在窗口添加流程(一)中,有这个方法:

http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/view/ViewRootImpl.java#1314

    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,int userId) {
...// Schedule the first layout -before- adding to the window// manager, to make sure we do the relayout before receiving// any other events from the system.requestLayout();
...}

2. ViewRootImpl#requestLayout

requestLayout中的scheduleTraversals是一个异步方法

    @Overridepublic void requestLayout() {if (!mHandlingLayoutInLayoutRequest) {checkThread();mLayoutRequested = true;
//异步方法scheduleTraversals();}}

3. ViewRootImpl#scheduleTraversals

scheduleTraversals中有一个Runnable方法

关于Choreographer编舞者,这里也不重点介绍。

    final class TraversalRunnable implements Runnable {@Overridepublic void run() {
//执行view遍历操作,进行measure,layout,draw操作doTraversal();}}final TraversalRunnable mTraversalRunnable = new TraversalRunnable();@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)void scheduleTraversals() {if (!mTraversalScheduled) {mTraversalScheduled = true;mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
//Choreographer Posts a callback to run on the next frame.
// The callback runs once then is automatically removed.mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);notifyRendererOfFramePending();pokeDrawLockIfNeeded();}}

4. ViewRootImpl#doTraversal

来看看Runnable中的方法

void doTraversal() {if (mTraversalScheduled) {mTraversalScheduled = false;mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
...
//要执行到了真正的遍历操作,这就要对view执行measure,layout, draw流程了performTraversals();
...}}

5. ViewRootImpl#performTraversals

    private void performTraversals() {
...// cache mView since it is used so much below...
//这个mView是通过setView方法传进来的,也就是Activity的根布局DecorView,使用final修饰,以防在遍历过程中被修改final View host = mView;
...
//mAdded指DecorView是否被成功加入到window中,在setView()中被赋值为trueif (host == null || !mAdded) {mLastPerformTraversalsSkipDrawReason = host == null ? "no_host" : "not_added";return;}
...mIsInTraversal = true;//是否正在遍历mWillDrawSoon = true;//是否需要马上绘制boolean cancelDraw = false;String cancelReason = null;boolean isSyncRequest = false;boolean windowSizeMayChange = false;WindowManager.LayoutParams lp = mWindowAttributes;
//顶层视图DecorView窗口的期望宽高int desiredWindowWidth;int desiredWindowHeight;
//DecorView是否可见final int viewVisibility = getHostVisibility();
//视图可见性改变final boolean viewVisibilityChanged = !mFirst&& (mViewVisibility != viewVisibility || mNewSurfaceNeeded// Also check for possible double visibility update, which will make current// viewVisibility value equal to mViewVisibility and we may miss it.|| mAppVisibilityChanged);
...WindowManager.LayoutParams params = null;
...boolean windowShouldResize = layoutRequested && windowSizeMayChange&& ((mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight())|| (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT &&frame.width() < desiredWindowWidth && frame.width() != mWidth)|| (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT &&frame.height() < desiredWindowHeight && frame.height() != mHeight));windowShouldResize |= mDragResizing && mPendingDragResizing;
...
//第一次执行测量布局绘制操作||Activity窗口大小需要改变||View的可见性发生了变化||窗口属性发生了变化||ViewRootHandler接收到消息MSG_RESIZED_REPORT,即size改变了if (mFirst || windowShouldResize || viewVisibilityChanged || params != null|| mForceNextWindowRelayout) {
...
//如果此窗口为窗口管理器提供内部insets,那么我们首先要在布局期间使提供的insets保持不变。
//这样可以避免它短暂地导致其他窗口根据窗口的原始框架调整大小/移动,
//等到我们完成此窗口的布局并返回窗口管理器,并最终计算出插图。insetsPending = computesInternalInsets;
...
//判断是否有surfaceboolean hadSurface = mSurface.isValid();try {
...if (mFirst || viewVisibilityChanged) {mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;}
//params,窗口属性变化内容
//请求WMS计算Activity窗口大小及边衬区域大小relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...// Ask host how big it wants to be//绘制三部曲之measureperformMeasure(childWidthMeasureSpec, childHeightMeasureSpec);...//绘制三部曲之layoutperformLayout(lp, mWidth, mHeight);...//绘制三部曲之drawperformDraw();
...

6. ViewRootImpl#relayoutWindow

我们主要是来看看ViewRootImpl如何向WMS申请布局的

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,boolean insetsPending) throws RemoteException {
...
//window申请的宽final int requestedWidth = (int) (measuredWidth * appScale + 0.5f);
//window申请的高final int requestedHeight = (int) (measuredHeight * appScale + 0.5f);int relayoutResult = 0;mRelayoutSeq++;if (relayoutAsync) {mWindowSession.relayoutAsync(mWindow, params,requestedWidth, requestedHeight, viewVisibility,insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq,mLastSyncSeqId);} else {
//请求重新布局relayoutResult = mWindowSession.relayout(mWindow, params,requestedWidth, requestedHeight, viewVisibility,insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq,mLastSyncSeqId, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl,mTempInsets, mTempControls, mRelayoutBundle);
...

这里就又用到了AIDL,WindowSession,WindowSession是APP和WMS沟通的桥梁

   final IWindowSession mWindowSession;

可以看下这篇文章加强理解

Android14 WMS-IWindowSession介绍-CSDN博客

7. Session #relayout

 

//Session继承了IWindowSession.Stub
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
...@Overridepublic int relayout(IWindow window, WindowManager.LayoutParams attrs,int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,int lastSyncSeqId, ClientWindowFrames outFrames,MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl,InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,Bundle outSyncSeqIdBundle) {if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "+ Binder.getCallingPid());Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
//调用到了Server端int res = mService.relayoutWindow(this, window, attrs,requestedWidth, requestedHeight, viewFlags, flags, seq,lastSyncSeqId, outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,outActiveControls, outSyncSeqIdBundle);Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "+ Binder.getCallingPid());return res;}

8. WindowManagerService #relayoutWindow

Server端流程太多了,另起一篇文章分析。

 

 

相关文章:

Android14 WMS-窗口绘制之relayoutWindow流程(一)-Client端

Android14 WMS-窗口添加流程(一)-Client端-CSDN博客 Android14 WMS-窗口添加流程(二)-Server端-CSDN博客 经过上述两个流程后&#xff0c;窗口的信息都已经传入了WMS端。 1. ViewRootImpl#setView 在窗口添加流程(一)中&#xff0c;有这个方法&#xff1a; http://aospxref…...

JVM学习-Jprofiler

JProfiler 基本概述 特点 使用方便&#xff0c;界面操作友好对被分析的应用影响小(提供模板)CPU&#xff0c;Tread&#xff0c;Memory分析功能尤其强大支持对jdbc,noSql,jsp,servlet,socket进行分析支持多种模式(离线、在线)的分析支持监控本地、远程JVM跨平台&#xff0c;拥…...

Skins

本主题解释如何将DevExpress主题/皮肤应用到应用程序中&#xff0c;如何允许用户在运行时在主题之间切换&#xff0c;如何自定义现有皮肤或创建自己的皮肤&#xff0c;等等。 WinForms订阅包括许多基本控件&#xff1a;按钮、复选框、表单、消息框、对话框、对话框等。 我们实现…...

【Meetup】探索Apache SeaTunnel的二次开发与实战案例

在数据科技快速演进的今天&#xff0c;业务场景的复杂化和数据量的激增&#xff0c;推动了大数据技术的迅速发展&#xff0c;在众多开源大数据处理工具中&#xff0c;Apache SeaTunnel以其强大的数据集成能力&#xff0c;成为众多企业的首选。 但随着应用深入&#xff0c;企业面…...

嵌入式Linux系统中RTC应用的操作详解

第一:RTC的作用以及时间简介 “RTC”的英文全称是Reul-Time Clock,翻译过来是实时时钟芯片.实时时钟芯片是日常生活中应用最为广泛的电子器件之一,它为人们或者电子系统提供精确的实时时间,实时时钟芯片通过引脚对外提供时间读写接口,通常内部带有电池,保证在外部系统关…...

Edge 工作区是什么?它都有哪些作用?

什么是工作区 Edge 工作区是什么&#xff1f;它是微软 Edge 浏览器中的一个功能&#xff0c;在帮助用户更好地组织和管理他们的浏览会话。通过工作区&#xff0c;用户可以创建多个独立的浏览环境&#xff0c;每个工作区内包含一组相关的标签页和浏览器设置。这使得用户能够根据…...

Docker|了解容器镜像层(1)

引言 容器非常神奇。它们允许简单的进程表现得像虚拟机。在这种优雅的底层是一组模式和实践&#xff0c;最终使一切运作起来。在设计的根本是层。层是存储和分发容器化文件系统内容的基本方式。这种设计既出人意料地简单&#xff0c;同时又非常强大。在今天的帖子[1]中&#xf…...

vue3设置全局变量并获取 全局响应式变量 窗口大小

设置 js文件统一管理全局变量 方法1 app provide() 全局提供变量 通过inject()使用 方法2 app实例配置全局变量 获取 通过 getCurrentInstance.appContext.config.globalProperties.$innerWidth访问到 code import { ref } from vue export const useGlobalState () > {c…...

Java——面向对象进阶(一)

前言 面向对象进阶(一)&#xff1a;static&#xff0c;继承&#xff0c;this和super关键字 文章目录 一、static1.1 静态变量1.2 静态方法1.3 静态变量和静态方法在内存中 二、继承2.1 概念2.2 继承的特点和能继承什么2.3 继承中的重写2.4 this和super关键字 一、static 在 Jav…...

JDBC是什么?它如何工作?

一、JDBC概述 JDBC&#xff08;Java Database Connectivity&#xff09;是Java语言与数据库之间进行交互的API。它允许Java程序通过SQL&#xff08;结构化查询语言&#xff09;来执行各种数据库操作&#xff0c;如查询、更新、删除等。JDBC是Java应用程序访问数据库的标准方式…...

Qt:QDialogButtonBox的使用

QDialogButtonBox是Qt自带的按钮箱&#xff0c;通过枚举QDialogButtonBox::ButtonRole可以添加Qt定义按钮&#xff0c;或者通过方法QDialogButtonBox::addButton添加自定义的按钮。 // 自定义按钮。 button_box_ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonB…...

38页 | 工商银行大数据平台助力全行数字化转型之路(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 工商银行大数据平台 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&a…...

【Git】如何不管本地文件,强制git pull

要在 Git 中强制执行 git pull 操作&#xff0c;忽略本地文件的更改&#xff0c;可以按照以下步骤操作&#xff1a; 保存当前工作状态&#xff1a;如果你有未提交的更改&#xff0c;可以使用 git stash 将这些更改存储起来。 git stash强制拉取最新代码&#xff1a;使用 git re…...

MySQL 高级 - 第十一章 | 索引优化与查询优化

目录 第十一章 索引优化与查询优化11.1 数据准备11.2 索引失效案例11.2.1 全值匹配10.2.2 最佳左前缀法则10.2.3 主键插入顺序10.2.4 计算、函数、类型转换&#xff08;自动或手动&#xff09;导致索引失效10.2.5 范围条件右边的列索引失效10.2.6 不等于&#xff08;! 或者 <…...

工厂模式——工厂方法模式+注册表

工厂方法模式的瑕疵 在前一篇笔记中我们介绍了工厂方法模式&#xff0c;示例的类图如下&#xff1a; 考虑一种情况&#xff1a;现在要在程序运行时&#xff0c;根据外部资源&#xff0c;动态的实例化对象。也就是说在编译期我们无法知道要实例化的对象的类型。因此在实例化的过…...

实验一、网络传输介质————双绞线 《计算机网络》

蝙蝠身上长鸡毛&#xff0c;忘了自己是什么鸟。 目录 一、实验目的 二、实验内容 1.双绞线的原理以及分类 2.了解双绞线的性质、结构与特性 3.掌握双绞线的制作方法 4.了解双绞线的材质 5.了解双绞线的发展趋势 三、实验小结 一、实验目的 1.双绞线的原理以及分类 2.了…...

在Linux/Ubuntu/Debian中使用lshw查看系统信息

在Linux/Ubuntu/Debian中使用lshw查看系统信息 lshw 是一个用于显示硬件配置的命令&#xff0c;可以提供系统硬件的详细信息&#xff0c;包括 CPU、内存、硬盘、主板等。该命令需要超级用户权限来获取详细信息。 常见用法&#xff1a; 显示所有硬件信息&#xff1a; sudo l…...

提高篇(八):扩展Processing功能:从库使用到跨平台应用

提高篇(八):扩展Processing功能:从库使用到跨平台应用 引言 Processing是一款强大的创意编程工具,广泛应用于艺术、设计和教育等领域。但其真正的魅力在于其可扩展性:你可以通过使用各种扩展库、结合其他编程语言、在不同硬件平台上应用,甚至创建自己的扩展库来丰富Pro…...

ubuntu18.04环境下,arduino ide在打开串口监视器时报错

ubuntu18.04环境下&#xff0c;arduino ide在打开串口监视器时报错 Exception in thread “AWT-EventQueue-0” java.lang.UnsatisfiedLinkError: /home/lzx/.jssc/linux/libjSSC-2.8_x86_64.so: /home/lzx/.jssc/linux/libjSSC-2.8_x86_64.so: file too short 这个错误表明 li…...

码蹄集部分题目(2024OJ赛18期;并查集+ST表+贪心)

1&#x1f40b;&#x1f40b;史莱姆融合&#xff08;钻石&#xff1b;并查集&#xff09; 时间限制&#xff1a;1秒 占用内存&#xff1a;128M &#x1f41f;题目描述 &#x1f41f;题目思路 这道题目使用并查集&#xff0c;同一集合的所有元素的最顶上的祖父节点是统一的。…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...