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

相关文章

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Redis分布式锁使用及说明

《Redis分布式锁使用及说明》本文总结了Redis和Zookeeper在高可用性和高一致性场景下的应用,并详细介绍了Redis的分布式锁实现方式,包括使用Lua脚本和续期机制,最后,提到了RedLo... 目录Redis分布式锁加锁方式怎么会解错锁?举个小案例吧解锁方式续期总结Redis分布式锁如果追求

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

关于SpringBoot的spring.factories文件详细说明

《关于SpringBoot的spring.factories文件详细说明》spring.factories文件是SpringBoot自动配置机制的核心部分之一,它位于每个SpringBoot自动配置模... 目录前言一、基本结构二、常见的键EnableAutoConfigurationAutoConfigu

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo