本文约4.8千字,新手阅读需要8分钟,复习需要3分钟 【收藏随时查阅不再迷路】
众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣 !!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎私我,交流群让学习不再孤单。
这是小空坚持写的Android新手向系列,欢迎品尝。
大佬(√)
新手(√√√)
敲黑板了,敲黑板了,这节是很大的环节,涉及知识很多,建议收藏。
如果你想要显示实时视频流(也就是在线视频)或任何内容流(如OpenGL 场景),则可以使用 Android 提供的 TextureView 来实现该需求。
首先,我们需要先熟悉三个概念:SurfaceView, TextureView, SurfaceTexture
从设计之初,该控件就存在了,她继承自View,但又与普通View不同,那就是拥有自己的Surface。
我们知道Android中页面会组成View树形结构,只有在顶层的DecorView才是可见的,相反SurfaceView她的工作方式是创建一个区别于应用窗口的新窗口(拥有自己的Layer,是独立的View),,与宿主窗口分离不受其控制,这拥有明显的好处就是可以在不同的线程中处理业务(有时你发现程序命名bug崩溃了但是还在显示就是因为这个原因)。效率很高,尤其是游戏方面渲染方面承担重任。
所以总结一句话就是,她与宿主窗口分离,有独立的上下文context,因此可以在单独线程中处理业务,不受View的属性控制,无法进行平移缩放等转换,不能放到ViewGroup中。
SurfaceView的核心在于提供了两个线程:UI线程和渲染线程,这两个线程通过“双缓冲”机制来达到高效的界面刷新效果。可以通俗的这么理解:不需要画布,直接在窗口上进行绘图叫做无缓冲绘图。使用一个画布,将所有内容都先画到画布上,然后在整体绘制到窗口上,可以称为单缓冲绘图,那个画布就是一个缓冲区。用了两个画布,一个进行临时的绘图,一个进行最终的绘图,这样就叫做双缓冲。这种机制可以使画面更加流畅的运行。
继承自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加速提高了绘制效率。
随着时间的推移以及需求的多样性,单纯的SurfaceView已经不满足要求了,所以增加了GLSurfaceView和SurfaceTexture。
和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后可以交给GLSurfaceView直接显示,也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。
好家伙,随着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则更加适合。
最后,总结下这几者的区别和联系。
📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。
温馨提示:点击下方卡片获取更多意想不到的资源。