Android修行手册 - TextureView和SurfaceView说明

2023-12-16 19:59

本文主要是介绍Android修行手册 - TextureView和SurfaceView说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

往期文章分享
  • 点击跳转=>《导航贴》- Unity手册,系统实战学习
  • 点击跳转=>《导航贴》- Android手册,重温移动开发

本文约4.8千字,新手阅读需要8分钟,复习需要3分钟收藏随时查阅不再迷路

👉关于作者

众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣 !!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎私我,交流群让学习不再孤单

在这里插入图片描述

👉前提

这是小空坚持写的Android新手向系列,欢迎品尝。

大佬(√)

新手(√√√)

👉实践过程

敲黑板了,敲黑板了,这节是很大的环节,涉及知识很多,建议收藏。

如果你想要显示实时视频流(也就是在线视频)或任何内容流(如OpenGL 场景),则可以使用 Android 提供的 TextureView 来实现该需求。

首先,我们需要先熟悉三个概念:SurfaceView, TextureView, SurfaceTexture

😜SurfaceView

从设计之初,该控件就存在了,她继承自View,但又与普通View不同,那就是拥有自己的Surface

我们知道Android中页面会组成View树形结构,只有在顶层的DecorView才是可见的,相反SurfaceView她的工作方式是创建一个区别于应用窗口的新窗口(拥有自己的Layer,是独立的View),,与宿主窗口分离不受其控制,这拥有明显的好处就是可以在不同的线程中处理业务(有时你发现程序命名bug崩溃了但是还在显示就是因为这个原因)。效率很高,尤其是游戏方面渲染方面承担重任。

image.png
所以总结一句话就是,她与宿主窗口分离,有独立的上下文context,因此可以在单独线程中处理业务,不受View的属性控制,无法进行平移缩放等转换,不能放到ViewGroup中。

SurfaceView的核心在于提供了两个线程:UI线程和渲染线程,这两个线程通过“双缓冲”机制来达到高效的界面刷新效果。可以通俗的这么理解:不需要画布,直接在窗口上进行绘图叫做无缓冲绘图。使用一个画布,将所有内容都先画到画布上,然后在整体绘制到窗口上,可以称为单缓冲绘图,那个画布就是一个缓冲区。用了两个画布,一个进行临时的绘图,一个进行最终的绘图,这样就叫做双缓冲。这种机制可以使画面更加流畅的运行。

😜GLSurfaceView

继承自SurfaceView,她实现了SurfaceHolder.Callback2接口,既然是继承的那么SurfaceView的全部特性她都有,不仅如此,还有view所有的功能和属性,特别是处理事件的能力,它主要是在SurfaceView的基础上它加入了EGL的管理,并自带了一个GLThread绘制线程(EGLContext创建GL环境所在线程即为GL线程),绘制的工作直接通过OpenGL在绘制线程进行,且不会阻塞主线程,然后将绘制出的结果输出到SurfaceView所提供的Surface上,因此这使得GLSurfaceView也拥有了OpenGlES所提供的图形处理能力,还有个Render接口来支持用户自定义渲染器,通过该接口,使Render的操作行为变得非常灵活,只需要将实现了渲染函数的Renderer的实现类设置给GLSurfaceView即可。

区别于View的Skia渲染方式,GLSurfaceView的渲染器Renderer使用opengl绘制引擎进行渲染。因此具有GPU加速的特点,GLSurfaceView的效率是SurfaceView的30倍以上,SurfaceView使用画布进行绘制,GLSurfaceView利用GPU加速提高了绘制效率。

😜SurfaceTexture

随着时间的推移以及需求的多样性,单纯的SurfaceView已经不满足要求了,所以增加了GLSurfaceView和SurfaceTexture。

和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后可以交给GLSurfaceView直接显示,也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。

😜TextureView

好家伙,随着Android系统进一步发展,人们的要求越来越“变态”,再次增加了TextureView的概念。与SurfaceView相比,TextureView并没有重新创建一个新的单独的Surface用来绘制操作。

TextureView继承自View,她可以将内容流直接投射到普通View中,可以用于实现Live preview等功能。和SurfaceView不同的是,它不会在Window Mananger Services中单独创建窗口,就像是一般的View一样作为View hierachy中的一份子,因此与其它的View一样在View hierachy中管理与绘制。,所以可以和其它普通View一样可以进行移动,旋转,缩放,动画等变化。它显示的内容流数据可以来自App进程或是远端进程。但需要特别注意的是TextureView必须在硬件加速的窗口中(如果关闭硬件加速,GLES被禁用,TextureView就不能做任何事情),并且消费的内存要比SurfaceView多,并且伴有一定的延迟。

至于卡顿和抖动的更深层剖析,可参考大佬文章:https://zhuanlan.zhihu.com/p/147322501

SurfaceView是通过SurfaceHolder.addCallback方法在子线程中更新UI,TextureView则可以通过TextureView.setSurfaceTextureListener在子线程中更新UI。

对于一些类似于需要不断告诉更新画布的游戏来说,SurfaceView绝对是很不错的选择。但是比如视频播放或相机的开发,TextureView则更加适合。

最后,总结下这几者的区别和联系。

  • 简单地说:SurfaceView直接输出的,拥有自己独立Surface的View, 它的渲染可以放在单独线程而不是主线程中, 其缺点是不能做变形和动画。
  • SurfaceTexture可以用在非直接输出的内容流上,这样就提供了可以进行二次处理的机会。也同样带来了隐患,这样会有若干帧的延迟。同时,由于它本身管理BufferQueue,因此内存消耗也会稍微大一些。
  • TextureView是一个可以把内容流作为外部纹理输出的, 她本身必须是一个硬件加速层。由于失效(invalidation)和缓冲的特性,TextureView增加了额外1~3帧的延迟显示画面更新。
  • 事实上TextureView本身也包含了SurfaceTexture, 它与SurfaceView+SurfaceTexture组合相比可以完成类似的功能(即把内容流上的图像转成纹理,然后输出), 区别在于TextureView是在View hierachy中做绘制,因此一般它是在主线程上做的(在Android 5.0引入渲染线程后,它是在渲染线程中做的)。而SurfaceView+SurfaceTexture在单独的Surface上做绘制,可以是用户提供的线程,而不是系统的主线程或是渲染线程。
  • 在Android 7.0上系统 Surfaceview 的性能比 TextureView 更有优势,支持对象的内容位置和包含的应用内容同步更新,平移、缩放不会产生黑边。在7.0以下系统如果使用场景有动画效果,可以选择性使用TextureView。
  • TextureView比SurfaceView使用更多的内存。

👉其他

📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。

温馨提示点击下方卡片获取更多意想不到的资源。
空名先生

这篇关于Android修行手册 - TextureView和SurfaceView说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/501705

相关文章

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Python sys模块的使用及说明

《Pythonsys模块的使用及说明》Pythonsys模块是核心工具,用于解释器交互与运行时控制,涵盖命令行参数处理、路径修改、强制退出、I/O重定向、系统信息获取等功能,适用于脚本开发与调试,需... 目录python sys 模块详解常用功能与代码示例获取命令行参数修改模块搜索路径强制退出程序标准输入

MySQL之复合查询使用及说明

《MySQL之复合查询使用及说明》文章讲解了SQL复合查询中emp、dept、salgrade三张表的使用,涵盖多表连接、自连接、子查询(单行/多行/多列)及合并查询(UNION/UNIONALL)等... 目录复合查询基本查询回顾多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.