什么是 SurfaceView?

surface简介

Surface这个词可以理解为“表面”,在内存中,它对应的是一个绘图缓冲区。根据SDK文档的描述,Surface被定义为“由屏幕显示内容合成器(screen compositor)所管理的原生缓冲器的句柄”。这句话有两个重要含义:首先,通过Surface(作为句柄)可以访问到原生缓冲器及其内容,类似于在C语言中通过文件句柄访问文件内容;其次,原生缓冲器(raw buffer)用于存储当前窗口的像素数据。简而言之,Surface对应的是一块屏幕缓冲区,每个Window对应一个Surface,所有的View都绘制在Surface上。传统的View共享一块屏幕缓冲区,且所有绘制操作必须在UI线程中进行。我们不能直接操作Surface实例,而是需要通过SurfaceHolder来进行操作,在SurfaceView中可以通过getHolder()方法获取到SurfaceHolder实例。Surface是一个用于绘图的地方,但绘图操作是在Canvas对象上进行的,Surface中的Canvas成员提供了一个类似黑板的绘图空间,而原始缓冲区则用于存储数据。Surface本身类似于一个句柄,通过这个句柄可以访问到其中的Canvas、原始缓冲区以及其他内容,因此,Surface可以被视为用于管理数据的句柄。

SurfaceView简介

简单来说,SurfaceView是一个内嵌了Surface的View,专门用于绘图。SurfaceView控制Surface的格式、尺寸和绘制位置。SurfaceView就像在Window上挖的一个洞,它的内容显示在这个洞里,而其他View则显示在Window上,因此View可以显示在SurfaceView之上,也可以在SurfaceView上添加其他层。

代码语言:javascript代码运行次数:0

运行复制“`javascriptif (mWindow == null) { mWindow = new MyWindow(this); mLayout.type = mWindowType; mLayout.gravity = Gravity.LEFT|Gravity.TOP; mSession.addWithoutInputChannel(mWindow, mWindow.mSeq, mLayout, mVisible ? VISIBLE : GONE, mContentInsets);}“`

显然,每个SurfaceView在创建时都会生成一个MyWindow,new MyWindow(this)中的this正是SurfaceView自身,因此将SurfaceView和Window绑定在一起。前面提到每个Window对应一个Surface,因此SurfaceView内嵌了自己的Surface,可以认为SurfaceView是用来控制Surface的位置和尺寸的。传统的View及其派生类只能在UI线程中更新,而UI线程还需处理其他交互逻辑,这无法保证View更新的速度和帧率。SurfaceView则可以使用独立的线程进行绘制,因此能提供更高的帧率,适合于游戏、摄像头取景等场景。

Surface是纵深排序(Z-ordered)的,这意味着它总是位于自己所在窗口的后面。SurfaceView提供了一个可见区域,只有在这个可见区域内的Surface内容才可见,可见区域外的部分不可见。因此,可以认为SurfaceView是展示Surface中数据的地方,而Surface是管理数据的地方,只有通过SurfaceView才能展示Surface中的数据。

什么是 SurfaceView?

Surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会显示在顶端。这意味着Surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays),例如文本和按钮等控件。注意,如果Surface上面有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。SurfaceView变得可见时,Surface被创建;SurfaceView隐藏前,Surface被销毁。这样能节省资源。如果你要查看Surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)。

SurfaceView的核心在于提供了两个线程:UI线程和渲染线程,这两个线程通过“双缓冲”机制来实现高效的界面实时更新。这个双缓冲可以理解为,SurfaceView在更新视图时使用了两张Canvas,一张是frontCanvas,一张是backCanvas。每次实际显示的是frontCanvas,而backCanvas存储的是上一次更改前的视图。当使用lockCanvas()获取画布时,得到的是backCanvas而不是正在显示的frontCanvas。之后你在获取到的backCanvas上绘制新视图,再unlockCanvasAndPost(canvas)此视图,那么上传的这张canvas将替换原来的frontCanvas作为新的frontCanvas,原来的frontCanvas将切换到后台作为backCanvas。例如,如果你已经先后两次绘制了视图A和B,那么你再调用lockCanvas()获取视图,获得的将是A而不是正在显示的B,之后你将重绘的C视图上传,那么C将取代B作为新的frontCanvas显示在SurfaceView上,原来的B则转换为backCanvas。无缓冲绘图是直接在窗口上进行绘图,单缓冲绘图是将所有内容先画到一个画布上,再整体绘制到窗口上,而双缓冲则使用两个画布,一个进行临时的绘图,一个进行最终的绘图。

Layx是一款网页弹窗Javript插件 Layx是一款网页弹窗Javript插件

Layx 是一款网页弹窗Javript插件,她将助力于互联网Web开发,提供优质的弹窗体验

Layx是一款网页弹窗Javript插件 32 查看详情 Layx是一款网页弹窗Javript插件

SurfaceView的优缺点:一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DectorView对WMS可见,这个DecorView在WMS中有一个对应的WindowState,在SurfaceFlinger中有对应的Layer,而SurfaceView因为有自己的Surface和Window,在WMS中有对应的WindowState,在SurfaceFlinger中有Layer。虽然在App端它仍在View hierachy中,但在Server端(WMS和SurfaceFlinger)中,它与宿主窗口是分离的。这样做的好处是可以将对这个Surface的渲染放到单独的线程中进行,并且可以有自己的GL context。因为它不会影响主线程对时间的响应,所以它的优点是可以在独立的线程中绘制,不影响主线程,而且使用双缓冲机制,播放视频时画面更顺畅。但这也有缺点,因为这个Surface不在View hierachy中,它的显示不受View的属性控制,所以不能进行平移、缩放等动画,它也不能放在其它ViewGroup中,SurfaceView不能嵌套使用,而且不能使用某些View的特性,例如View.setAlpha()。

从Android7.0开始,SurfaceView的窗口位置与其他View渲染同步更新。这意味着在屏幕上平移和缩放SurfaceView不会导致渲染失真。

SurfaceHolder简介

SurfaceHolder是一个显示Surface的抽象接口,允许你控制Surface的大小和格式,并在Surface上编辑像素,同时监视Surface的变化。这个接口通常通过SurfaceView类实现。简单来说,我们无法直接操作Surface,只能通过SurfaceHolder这个接口来获取和操作Surface。SurfaceHolder中提供了一些方法,如lockCanvas():获取一个Canvas对象,并锁定之。所得到的Canvas对象实际上是Surface中的一个成员。加锁的目的是为了在绘制的过程中,Surface中的数据不会被改变。lockCanvas是为了防止同一时刻多个线程对同一canvas写入。

从设计模式的角度来看,Surface、SurfaceView、SurfaceHolder实质上就是MVC(Model-View-Controller)模式。Model是模型或数据模型,这里指的是Surface;View是视图,代表用户交互界面,这里指的是SurfaceView;SurfaceHolder则是Controller。

我的博客即将同步至PHP中文网+社区,邀请大家一同入驻:https://www.php.cn/link/3a2ca3f7b805be6481955d28feb72a2b

以上就是什么是 SurfaceView?的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/400266.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月6日 19:10:46
下一篇 2025年11月6日 19:12:17

相关推荐

  • CSS元素设置em和transition后,为何载入页面无放大效果?

    css元素设置em和transition后,为何载入无放大效果 很多开发者在设置了em和transition后,却发现元素载入页面时无放大效果。本文将解答这一问题。 原问题:在视频演示中,将元素设置如下,载入页面会有放大效果。然而,在个人尝试中,并未出现该效果。这是由于macos和windows系统…

    2025年12月24日
    200
  • 如何模拟Windows 10 设置界面中的鼠标悬浮放大效果?

    win10设置界面的鼠标移动显示周边的样式(探照灯效果)的实现方式 在windows设置界面的鼠标悬浮效果中,光标周围会显示一个放大区域。在前端开发中,可以通过多种方式实现类似的效果。 使用css 使用css的transform和box-shadow属性。通过将transform: scale(1.…

    2025年12月24日
    200
  • 如何用HTML/JS实现Windows 10设置界面鼠标移动探照灯效果?

    Win10设置界面中的鼠标移动探照灯效果实现指南 想要在前端开发中实现类似于Windows 10设置界面的鼠标移动探照灯效果,有两种解决方案:CSS 和 HTML/JS 组合。 CSS 实现 不幸的是,仅使用CSS无法完全实现该效果。 立即学习“前端免费学习笔记(深入)”; HTML/JS 实现 要…

    2025年12月24日
    000
  • 如何用前端实现 Windows 10 设置界面的鼠标移动探照灯效果?

    如何在前端实现 Windows 10 设置界面中的鼠标移动探照灯效果 想要在前端开发中实现 Windows 10 设置界面中类似的鼠标移动探照灯效果,可以通过以下途径: CSS 解决方案 DEMO 1: Windows 10 网格悬停效果:https://codepen.io/tr4553r7/pe…

    2025年12月24日
    000
  • 如何用前端技术实现Windows 10 设置界面鼠标移动时的探照灯效果?

    探索在前端中实现 Windows 10 设置界面鼠标移动时的探照灯效果 在前端开发中,鼠标悬停在元素上时需要呈现类似于 Windows 10 设置界面所展示的探照灯效果,这其中涉及到了元素外围显示光圈效果的技术实现。 CSS 实现 虽然 CSS 无法直接实现探照灯效果,但可以通过以下技巧营造出类似效…

    2025年12月24日
    000
  • 移动端rem计算导致页面扭曲变动如何解决?

    解决移动端rem计算导致页面扭曲变动的问题 在移动端项目中使用rem作为根节点字体大小的计算方式时,可能会遇到页面首次打开时出现css扭曲变动的现象。这是因为根节点字体大小赋值后,会导致页面内容重绘。 解决方法: 将计算根节点字体大小的js代码移动到页面的最开头,放置在 标签内。 原理: 这样做可以…

    2025年12月24日
    200
  • Nuxt 移动端项目中 rem 计算导致 CSS 变形,如何解决?

    Nuxt 移动端项目中解决 rem 计算导致 CSS 变形 在 Nuxt 移动端项目中使用 rem 计算根节点字体大小时,可能会遇到一个问题:页面内容在字体大小发生变化时会重绘,导致 CSS 变形。 解决方案: 可将计算根节点字体大小的 JS 代码块置于页面最前端的 标签内,确保在其他资源加载之前执…

    2025年12月24日
    200
  • Nuxt 移动端项目使用 rem 计算字体大小导致页面变形,如何解决?

    rem 计算导致移动端页面变形的解决方法 在 nuxt 移动端项目中使用 rem 计算根节点字体大小时,页面会发生内容重绘,导致页面打开时出现样式变形。如何避免这种现象? 解决方案: 移动根节点字体大小计算代码到页面顶部,即 head 中。 原理: flexível.js 也遇到了类似问题,它的解决…

    2025年12月24日
    000
  • 如何避免使用rem计算造成页面变形?

    避免rem计算造成页面变形 在使用rem计算根节点字体大小时,可能会遇到页面在第一次打开时出现css扭曲变动的现象。这是因为在浏览器运行到计算根节点字体大小的代码时,页面内容已经开始展示,随后根节点字体大小的赋值操作会导致页面内容重绘,从而产生变形效果。 要避免这种情况,可以在页面的最前面,也就是h…

    2025年12月24日
    000
  • 网页布局中,使用 translate 转换元素位置的优势有哪些?

    为什么考虑使用 translate 而非定位属性更改元素位置 在网页布局中,我们通常使用元素的定位属性(如 left、right、top、bottom)来控制元素在文档流中的位置。然而,在某些情况下,我们可能考虑使用 translate 转换来改变元素位置。 使用 translate 的优势: 不会…

    2025年12月24日
    000
  • 为什么使用 `translate` 比修改定位改变元素位置更有效?

    为什么使用 translate 而不是修改定位来改变元素位置? 在某些情况下,使用 translate 而不是修改元素的定位来改变其位置更具优势。 原因如下: 减少重绘和重排:改变 transform 不会触发重排或重绘,只会触发复合。而修改元素定位可能会触发重排,代价更高。动画更平滑:使用 tra…

    2025年12月24日
    000
  • 浮动元素修改宽高,是否会触发布局调整?

    浮动元素自有其渲染之法,修改宽高影响布局否? 浮动元素的存在使文本内容对其环绕,倘若对其宽高频繁修改,是否会触发大规模的布局调整? 让我们从分层与渲染视角着手,进一步探究问题的答案。 从分层来看,浮动元素与其相邻元素处于同一层级。而从渲染角度观察,图像的绘制(paint)可被称作重绘,布局(layo…

    2025年12月24日
    000
  • 修改浮动元素宽高会触发重排吗?

    修改浮动元素宽高后是否会触发重排 众所周知,浮动元素会影响与其相邻文本内容的位置。那么,如果对一个浮动元素反复修改其宽高,会否引发大规模重排呢? 根据浏览器的分层机制和渲染流程,浮动元素与其相邻元素位于同一层。在分层渲染中,”paint”对应重绘,”layout&…

    2025年12月24日
    200
  • 反复修改浮动元素宽高会触发重排吗?

    修改浮动元素宽高对重排的影响 众所周知,当浮动元素出现时,相邻文本内容会环绕其排列。那么,反复修改浮动元素的宽高是否会触发重排呢? 影响布局,重排是必然 从渲染模型的角度来看,修改浮动元素的宽高将影响其布局,因为这改变了元素在文档流中的位置。具体来说,浮动元素的宽高修改将触发布局重排(layout)…

    2025年12月24日
    000
  • 修改浮动图片元素的宽高会触发重排吗?

    对浮动元素修改宽高的操作是否会触发重排 众所周知,设置浮动属性的图片元素会使相邻文本内容在其周围环绕。那么,如果对这样的图片元素反复修改宽高,是否会出现大规模的重排呢?答案是肯定的。 原因如下: 布局层级影响 从布局层级来看,浮动的图片元素与相邻文本内容处于同一层级。当修改图片元素的宽高时,相邻文本…

    2025年12月24日
    400
  • 苹果浏览器网页背景图色差问题:如何解决背景图不一致?

    网页背景图在苹果浏览器上出现色差 一位用户在使用苹果浏览器访问网页时遇到一个问题,网页上方的背景图比底部的背景图明显更亮。 这个问题的原因很可能是背景图没有正确配置 background-size 属性。在 windows 浏览器中,背景图可能可以自动填满整个容器,但在苹果浏览器中可能需要显式设置 …

    2025年12月24日
    400
  • 苹果浏览器网页背景图像为何色差?

    网页背景图像在苹果浏览器的色差问题 在不同浏览器中,网站的背景图像有时会出现色差。例如,在 Windows 浏览器中显示正常的上层背景图,在苹果浏览器中却比下层背景图更亮。 问题原因 出现此问题的原因可能是背景图像未正确设置 background-size 属性。 解决方案 为确保背景图像在不同浏览…

    2025年12月24日
    500
  • 苹果电脑浏览器背景图亮度差异:为什么网页上下部背景图色差明显?

    背景图在苹果电脑浏览器上亮度差异 问题描述: 在网页设计中,希望上部元素的背景图与页面底部的背景图完全对齐。而在 Windows 中使用浏览器时,该效果可以正常实现。然而,在苹果电脑的浏览器中却出现了明显的色差。 原因分析: 如果您已经排除屏幕分辨率差异的可能性,那么很可能是背景图的 backgro…

    2025年12月24日
    000
  • 如何在 VS Code 中解决折叠代码复制问题?

    解决 VS Code 折叠代码复制问题 在 VS Code 中使用折叠功能可以帮助组织长代码,但使用复制功能时,可能会遇到只复制可见部分的问题。以下是如何解决此问题: 当代码被折叠时,可以使用以下简单操作复制整个折叠代码: 按下 Ctrl + C (Windows/Linux) 或 Cmd + C …

    2025年12月24日
    000
  • css怎么用现代布局

    CSS 现代布局利用弹性盒布局和网格布局系统,提供了灵活、响应且模块化的方式来组织网页元素,轻松适应不同屏幕尺寸和设备。弹性盒布局适合创建单向布局,例如导航栏,而网格布局适用于设计复杂布局,如仪表板。使用弹性盒布局和网格布局时,可通过简单易用的 CSS 属性,控制元素尺寸、对齐方式和排列方向,实现响…

    2025年12月24日
    000

发表回复

登录后才能评论
关注微信