我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android中View.post和Handler.post的关系

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android中View.post和Handler.post的关系

目录

前言

为什么要拿这二者来比较?

View的渲染起点

View.post的执行流程

Handler.post()能像View.post()一样获取到宽、高数据吗?

前言

View.post和Handler.post是Android开发中经常使用到的两个”post“方法,我们经常通过前者去获取一些View在运行时的渲染数据,或者测量页面的渲染时间。而后者则是Android的核心Handler的一个方法,它会向对应线程的MessageQueue中插入一条Message,在未来的某个事件点得到执行.....

为什么要拿这二者来比较?

首先,这二者的名字相同

其次,是View.post()的调用时机和整个View的绘制和渲染有着千丝万缕的联系。而这一切的基础,正是主线程的Handler.post(),理清这二者的关系,能够加深我们对View渲染、绘制的流程的理解。

View的渲染起点

宏观上来说,当DecorView被”attach“到Window之上后,程序能够收到系统分配给各个Activity的同步信号时,View就会开始渲染了,当每个同步信号到来时,ChoreoGrapher将会派发出一个信号通知ViewRootImpl进行视图的渲染,因此,从系统上来看,每次释放的Vsync同步信号应该是视图绘制的起点。

从App端来说,当ScheduleTravesals被调用时,会先向MessageQueue中插入一个

消息屏障
,此时会阻隔其他的同步消息的通过,允许异步消息的进入。然后mChoreoGrapher,向MessageQueue中插入一个视图更新的信号,最终会走到doTraversals()方法中,在该方法的执行过程中,将会先取消掉同步屏障,然后紧接着执行performTraversals()方法。显然,
消息屏障
的作用就是提升peformTraversals的优先级,确保视图的优先绘制。

不难发现,真正的进行渲染的起点是

perfromTraversals()
方法:

View.post的执行流程

View.post在不同版本的Android系统中,有着不同的实现,在API24以前,View.post所做的是:当View.post被调用时,直接向ViewRootImpl的mRunQueue中插入一个Runnable,然后在performTraversals()过程中,统一进行处理,这样一来,View.post()就会按照View.post()的调用顺序在”未来的某个时间点“进行执行,这说明:在这一系列的Android版本中,View.post的执行顺序就是本身调用View.post()的顺序

处理:这里的处理并非直接执行Runnable,而是统一插入到主线程的MessageQueue中去执行;

“未来的某个时间点”,这个未来的某个时间点指的是perfromTraversals()中将ViewRootImpl中mRunQueue中的所有Runnable插入到MessageQueue之后的某个时间点。必然在performTraversals()之后。

如上图,必须得等到整个perfromTraversals方法体执行完成(包括)后,才有可能执行下一个Message(这里标注为了Runnable),而perfromTraversals()方法体中,会顺序地调用performMeasure()、performLayout()、performDraw()方法,这三个方法走完,意味着视图已经完成了渲染,此时的

View.post()执行,必然是能落在视图创建之后

而API24及之后的版本中,View.post所做的事情发生了改变,当View.post()调用时,Runnable被插入到View各自的mRunQueue当中,也就是说,每个View都含有一个mRunQueue,当performTraversals()中,也没有统一处理了,而是根据 

performTraversals()->dispatchAttachedToWindows()
递归地调用到子View时,子View将自己的mRunQueue插入到主线程的MessageQueue,这意味着:在高版本的执行过程中,View.post()的执行顺序是按照视图被迭代到的顺序。

不变的是

View.post()执行,必然是能落在视图创建之后
,这也是为什么能够调用View.post()来获取一些屏幕上的View的数据的原因。

Handler.post()能像View.post()一样获取到宽、高数据吗?

Activity为我们暴露了三个常用的生命周期函数:onCreate()、onStart()、onResume()。通常我们对一些事件的监听、View的初始化设置都会在这三个生命周期函数中实现,以最后执行的onReumse()为例,我们在其中使用主线程的Handler.post()获取一个视图的数据,

我们可以看看结果:

    override fun onResume(){
        super.onResume()
        Handler(Looper.getMainLooper()).post{
            Log.d("getHeight",textView.height.toString())
        }
    }
  D/getHeight: 0

显然,失败了。

我们知道,一个的Activity的创建初期,DecorView并不会直接就和Activity建立联系,建立联系的过程在

handleResumeActivity()
当中,此时的DecorView被attach到了Activity之上。但是,我们需要明确一点:一个View如果没有和Activity建立联系,那么它将收不到系统的同步信号,也就无法更新(更新也没有意义,因为它没有地方去显示),我们看看
handleResumeActiivty
的执行方法体,可以发现,先走了onResume()的回调,再走了a.mDecor = decor这一步骤,上文我们提到,视图更新的事件是以Message的形式,在MessageQueue中”排队“的,如果我们在onResume()中插入一个消息去获取渲染之后的宽高数据,那么这时的MessageQueue大概是这样:

当前正在执行的是黄色的Message,这是一个从ActivityThread.java中H类发出的调度方法,它将会调用到handleResumeActivity中的一系列方法,最终走到onResume这,我们使用Handler.post(),我们会发现消息被插在了黄色的Message之后,但是此时的

a.mDecor = decor
还没有执行,更不可能已经发生绘制了,这也就意味着压根没渲染,没视图,自然也没数据,完整的流程如下:

到此这篇关于Android中View.post和Handler.post的关系的文章就介绍到这了,更多相关View.post与Handler.post内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android中View.post和Handler.post的关系

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android中View.post和Handler.post的关系

目录前言为什么要拿这二者来比较?View的渲染起点View.post的执行流程Handler.post()能像View.post()一样获取到宽、高数据吗?前言 View.post和Handler.post是Android开发中经常使用到的
Android中View.post和Handler.post的关系
2022-06-07

Android中View.post和Handler.post的关系是什么

这篇文章主要介绍“Android中View.post和Handler.post的关系是什么”,在日常操作中,相信很多人在Android中View.post和Handler.post的关系是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好
2023-06-30

android中handler.post和handler.sendMessage的区别是什么

本篇文章给大家分享的是有关android中handler.post和handler.sendMessage的区别是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1. 异步更
2023-05-30

Android中屏幕密度和图片大小的关系详解

Android中屏幕密度和图片大小的关系详解前言Android中支持许多资源,包括图片(Bitmap),对应于bitmap的文件夹是drawable,除了drawable,还有drawable-ldpi、drawable-mdpi、draw
2023-05-31

c++中对象和类的关系

在 c++ 中,对象是类的具体实例,类是对象蓝图。对象拥有类的特性(数据成员)和行为(成员函数),而类定义对象的特性和行为规范。对象通过类创建,使用类成员函数访问特性和行为,而类则不能直接使用对象,但可以通过静态成员函数访问对象共享的数据或
c++中对象和类的关系
2024-05-10

mysql中groupby和having的关系

group by 分组数据后,having 子句针对分组进行过滤,仅保留符合条件的分组。二者结合用于分组数据、聚合数据、过滤分组、分析数据,查找模式趋势,汇总信息和创建统计报告。MySQL 中 GROUP BY 和 HAVING 子句的关系
mysql中groupby和having的关系
2024-04-26

c++中类和对象的关系

类定义数据和操作,而对象是类的具体实例,包含并执行这些数据和操作。类提供通用模板,对象是模板的实现;类定义属性和行为,对象存储数据值并执行行为;类是静态的,对象是动态的;对象实例化自类,继承其数据和操作;类支持派生类和多态性。C++ 中类和
c++中类和对象的关系
2024-05-08

在android开发环境中,gradle 版本和 java 版本的对应关系

在android开发环境中,gradle 版本和 java 版本的对应关系 Gradle 版本所支持的 JDK 版本6.xJDK 8、JDK 11(仅限 Gradle 6.7 及更高版本)5.xJDK 7、JDK 84.xJDK 6、JDK
2023-08-30

mysql中where和having的关系

where 子句过滤行级别数据,而 having 子句过滤组级别数据。where 子句在 from 关键字后应用,而 having 子句在 group by 关键字后应用。MySQL 中 WHERE 和 HAVING 子句的关系WHERE
mysql中where和having的关系
2024-05-01

Android中同步与异步的关系是什么

本篇文章为大家展示了Android中同步与异步的关系是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。android 只有UI线程可以刷新界面,其他副线程不行,这样就需要副线程通过通信消息修改刷新
2023-06-19

jdk和jre的关系

JDK(Java Development Kit)和JRE(Java Runtime Environment)是Java开发和运行的两个重要组件。JDK是Java开发工具包,它包含了Java开发人员需要的各种工具和库,用于开发、调试和编译J
2023-09-15

navicat和MySQL的关系

navicat是mysql数据库的管理工具,关系包括:连接和访问:navicat可连接mysql服务器并管理数据库和数据。查询和数据操作:内置sql编辑器和数据操作工具,可执行查询和操作数据。数据库设计:提供erd建模工具,帮助设计数据模型
navicat和MySQL的关系
2024-04-22

sql中 and和or的优先级关系

sql 中,and 运算符优先级高于 or 运算符。运算符执行顺序为:括号、not、and、or。使用括号可以修改执行顺序,优先执行括号内的表达式。SQL 中 AND 和 OR 的优先级关系在 SQL 中,逻辑运算符 AND 和 OR 用
sql中 and和or的优先级关系
2024-05-10

详谈Android中onTouch与onClick事件的关系(必看)

这几天遇到点关于Android的触摸事件相关的,还跟onClick有关,暂且记下: LinearLayout分别设置了onTouchListener,onClickListener,onLongClickListener及onTouchEv
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录