【Android】WMS(三)Window的更新&UI刷新

这篇具有很好参考价值的文章主要介绍了【Android】WMS(三)Window的更新&UI刷新。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Window的更新

【Android】WMS(三)Window的更新&UI刷新

在 Android 中,窗口的更新是一个非常常见的事情。比如,在使用 App 过程中,需要弹出键盘窗口或者切换横竖屏时,就会发生窗口的更新。

首先,当需要更新窗口时,会调用 WindowManagerupdateViewLayout() 方法来设置参数,并将参数设置到对应的 View 上。WindowManager 的实现类为 WindowManagerImpl,但它实际上并没有做太多的工作,而是直接委托给了 WindowManagerGlobal(WMGlobal)

接下来,在 updateViewLayout() 方法中,使用来同步更新,然后通过传入的 view 参数找到其在 DecorView 中的索引值,再根据索引值找到对应的 ViewRootImpl 对象。

由于所有的窗口都是由 ViewRootImpl 来管理的,因此我们需要调用 ViewRootImpl 的 setLayoutParams() 方法,来将新的布局参数设置到对应的 ViewRootImpl 上。在这个过程中,旧的布局参数会被移除,新的布局参数会被添加进去。

UI刷新

【Android】WMS(三)Window的更新&UI刷新

帧率

在移动设备上,为了确保操作界面的流畅性和用户体验,帧率(FPS)是非常重要的一个因素。帧率表示在一秒钟内刷新的图像帧数,表示界面绘制的速度,而较高的帧率则意味着更加流畅的操作体验。

在 Android 系统中,默认帧率为 60 FPS,在每 16 毫秒的时间内绘制一次界面。为了保证界面的流畅性,系统会通过 VSYNC 信号来同步帧率和屏幕刷新,从而保证在一个 VSYNC 周期内最多只绘制一帧,避免了过度绘制和渲染导致 CPU 和 GPU 的过度占用,优化了系统性能和电池寿命。因此,我们可以使用一些调试工具来监测帧率和绘制时间,以便了解系统的性能并进行优化。

请求刷新

在 Android 中,UI 的刷新并不是由应用程序自行决定的。相反,它需要向同步信号服务申请同步信号以进行刷新操作。应用程序在进行 UI 绘制之前必须先向系统申请同步信号,在得到系统同意后,才能开始实际的视图重绘。

在请求刷新时,应用程序会向系统注册一个回调函数,以便在同步信号到达时可以接收通知。当系统接收到请求时,它会分配一个时间片来准备重绘操作,并在准备完成后向应用程序发送同步信号。此时,应用程序的回调函数就会被调用,以便进行实际的重绘操作。

通过这种方式,Android 系统可以保证应用程序的刷新操作在正确的时机进行,并且不会占用过多的系统资源。同时,它还能够优化系统性能和电池寿命,提高用户体验。

UI的View刷新流程

View的内容变化会调用invalidate()方法,该方法会设置 ViewRootImpl 中的 mDirty 参数,表示需要重绘的区域。

紧接着在调用 invalidate() 方法后,ViewRootImpl 会执行 scheduleTraversals() 方法准备进行绘制操作。在此期间,ViewRootImpl 同时请求VSYNC信号。此请求的目的是为了在下一次刷新屏幕的同时绘制 View 并保证画面的流畅度。

调用 scheduleTraversals() 方法后,会将一个 mTraversalRunnable 对象加入 Choreographer.CALLBACK_TRAVERSAL 的队列中等待 VSYNC 信号到来。

在 VSYNC 信号到来后,Choreographer 会执行 mTraversalRunnable 中的 run() 方法,接着执行 doTraversal() 方法,进而调用 performTraversals() 方法。

在 performTraversals() 方法中,首先对输入的触摸事件进行处理,接着开始调用 View 的 measure()layout() draw() 方法,依次完成测量、布局和绘制的过程。

在绘制出来之后,ViewRootImpl 会通过Surface或者SurfaceView将界面显示到屏幕上。

UI绘制流程

【Android】WMS(三)Window的更新&UI刷新

UI局部刷新

UI局部刷新(Partial UI Refresh)指的是只对某些View进行重绘刷新,而不需要对整个屏幕进行重新绘制。实际上,在 Android 中实现 UI 局部刷新是非常重要且常见的需求,在某些情况下,仅针对一个或几个 View 进行重绘能够提升应用程序的性能和响应速度。

在 Android 中,实现 UI 局部刷新主要有两种方式:

invalidate(Rect dirty) 方法:该方法可以指定需要刷新的矩形区域,从而只会对该区域内的 View 进行重绘刷新。这种方式适用于实现需求简单的 UI 局部刷新,但是需要手动计算出需要刷新的矩形区域。

ViewOverlay:ViewOverlay 是一种可以叠加在 View 上方显示的视图,它的作用是为某个具体的 View 添加覆盖层。通过使用 ViewOverlay,我们可以在不影响原有 View 布局的情况下,动态添加、删除遮盖层,并且只需对遮盖层进行重绘刷新。这种方式可以实现比较复杂的 UI 局部刷新需求。

需要注意的是,对于使用了硬件加速的 View,使用 invalidate() 方法进行局部刷新时,可能会因为硬件加速的缓存机制导致 invalidate() 方法不会生效。此时,可以使用 setLayerType(View.LAYER_TYPE_SOFTWARE, null) 方法关闭硬件加速,或者使用 View.setClipChildren(false) 方法将 View 的父容器取消裁剪,从而避免这个问题。文章来源地址https://www.toymoban.com/news/detail-486555.html

到了这里,关于【Android】WMS(三)Window的更新&UI刷新的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android 13 WMS/AMS系统开发-窗口层级相关DisplayArea,WindowContainer

    官方注释: 给可以直接持有窗口的自己或它的孩子定义了一些公共的方法和属性,像RootWindowContainer、DisplayContent、DisplayArea、DisplayArea.Tokens、TaskDisplayArea、Task、ActivityRecord、WindowToken、WindowState都是直接或间接的继承该类。 这里面主要的重要要成员变量就是mParent和mChildren,一

    2024年02月16日
    浏览(40)
  • 论多窗口相互关联下window.open打开已在的窗口时只激活不刷新的实现方案

    前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言~博主看到后会去代替大家踩坑的~ 主页: oliver尹的主页 格言: 跌倒了爬起来就好~ 来个关注吧,点个赞吧,谢谢 近期,我司有个小伙伴遇到这么个场景实现起来感觉有点

    2024年02月04日
    浏览(58)
  • android 13 WMS/AMS系统开发-窗口层级相关DisplayArea,WindowContainer第二节

    接着上一节课学习,我们已经清楚的知道了层级结构应该怎么看,根据dumpsys的输出可以完美复原出层级结构树,也理解了结构树对于层级结构的控制作用。但还没有从源码部分对这个结构树进行一个分析,即分析生成这个结构树的源码部分。 结下来调用是实现类DefaultProvid

    2024年02月15日
    浏览(45)
  • Android窗口层级(Window Type)分析

    Android的窗口Window分为三种类型: 应用Window,比如 Activity 、 Dialog ;子Window,比如 PopupWindow ;系统Window,比如 Toast 、系统状态栏、导航栏等等。 应用Window的Z-Ordered最低,就是在系统中的显示层级最低,然后到子Window,层级最高的是系统Window。层级高的Window会覆盖层级低的W

    2024年02月09日
    浏览(41)
  • Android UI刷新机制与SurfaceView

    举例一个Activity的布局文件和逻辑如下: 当我们点击remove_btn时,会出现SurfaceView所在的区域会出现10s黑块的现象,这个现象在我们平时开发中用到SurafceView时常常遇到,往往在主线程同时存在耗时操作和SurfaceView detach操作的时候出现,那么为什么Surfaceview从parent view上面detach的

    2023年04月08日
    浏览(34)
  • Pyqt5实现新线程更新窗口UI

    我们用pyqt5开发窗口应用时,应用会执行一些耗时的操作,如复制大量文件,下载大量数据等。一般情况下,在这些操作没有完成时,窗口的UI处于“假死”状态,不会更新,只有所有操作完成后,窗口的状态才会更新。这样对用户使用非常不友好。 使用多线程技术,在新线

    2024年02月13日
    浏览(45)
  • Android Compose Column列表 数据更新列表不刷新的问题

    我们都知道, Compose 可以使用 mutableStateOf 和UI进行绑定,改变值之后,就可以改变UI。 效果如下 但是如果是使用 Column / Row / LazyColumn / LazyRow 列表的时候,无论怎么更新数据,界面都不会刷新 可以看到,点击了按钮后,列表完全没有刷新 这是为什么了 ? 当时很不解,为啥其他

    2023年04月16日
    浏览(40)
  • 带你深入理解Android 中 UI 的刷新机制

    Android中的UI刷新机制是指Android系统如何更新和绘制UI界面以响应用户的操作和数据变化。UI的刷新过程涉及到多个关键概念和组件,包括主线程、UI线程、消息循环、View树、View的测量和布局、绘制等。下面将详细解释Android中的UI刷新机制,并提供相应的代码示例。 主线程和

    2024年02月14日
    浏览(35)
  • Android Jetpack Compose之UI的重组和自动刷新

    我们都知道,在传统的View中,若要改变UI,需要我们修改View的私有属性,比如要修改一个TextView的文字,我们需要通过它的setText(“xxx”)方法去修改。而Compose 则是通过重组来刷新UI。在之前的状态管理的文章中也提到过重组的概念。本章主要就是介绍Compose的重组和刷新相关

    2024年02月07日
    浏览(49)
  • Android UI 线程更新UI也会崩溃??

    是不是有一丝的郁闷? 没关系,作为拥有多年经验的老鸟,总能立马想到解释的理由: 大家都知道在Activity#onCreate的时候,我们开个线程去执行Text#setText也不会崩溃,原因是ViewRootImpl那时候还没初始化,所以这次没崩溃也是一个原因。 对应源码解释是这样的: public void sho

    2024年03月24日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包