先看Surface

Surface的官方介绍:Handle onto a raw buffer that is being managed by the screen compositor,Surface是一个raw buffer的句柄,通过它在raw buffer上进行绘制,可以通过Surface获得一个Canvas。

Canvas canvas = mSurface.lockCanvas(null);
mSurface.unlockCanvasAndPost(canvas);

SurfaceView

SurfaceView对Surface进行了一次封装,它内部帮我们管理了一个Surface。我们使用SurfaceView其实最终都是获取到这个Surface去绘制,可参看官方解释:

Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen

The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.

The transparent region that makes the surface visible is based on the layout positions in the view hierarchy. If the post-layout transform properties are used to draw a sibling view on top of the SurfaceView, the view may not be properly composited with the surface.

Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by calling getHolder().

The Surface will be created for you while the SurfaceView's window is visible; you should implement SurfaceHolder.Callback#surfaceCreated and SurfaceHolder.Callback#surfaceDestroyed to discover when the Surface is created and destroyed as the window is shown and hidden.

One of the purposes of this class is to provide a surface in which a secondary thread can render into the screen. If you are going to use it this way, you need to be aware of some threading semantics:

  • All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread.
  • You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().

绘制过程:

  • 通过SurfaceHolder.getSurface可以获取到Surface;
  • 通过Surface.lockCanvas可以获取到Surface的Canvas;
  • 使用Canvas绘制图像;
  • 使用Surface.unlockCanvasAndPost可以释放Canvas。

GLSurfaceView

GLSurfaceView继承自SurfaceView,对SurfaceView又做了一次封装,方便我们在安卓中使用OpenGL。

GLSurfaceView提供了以下特性:

  • 提供并且管理一个独立的Surface;
  • 提供并且管理一个EGL display,它能让opengl把内容渲染到上述的Surface上;
  • 支持用户自定义渲染器(Render),通过setRenderer设置一个自定义的Renderer;
  • 让渲染器在独立的GLThread线程里运作,和UI线程分离;
  • 支持按需渲染(on-demand)和连续渲染(continuous)两种模式;
  • GPU加速:GLSurfaceView的效率是SurfaceView的30倍以上,SurfaceView使用画布进行绘制,GLSurfaceView利用GPU加速提高了绘制效率;
  • View的绘制onDraw(Canvas canvas)使用Skia渲染引擎渲染,而GLSurfaceView的渲染器Renderer的onDrawFrame(GL10 gl)使用opengl绘制引擎进行渲染。

参看官方解释:

An implementation of SurfaceView that uses the dedicated surface for displaying OpenGL rendering.

A GLSurfaceView provides the following features:

  • Manages a surface, which is a special piece of memory that can be composited into the Android view system.
  • Manages an EGL display, which enables OpenGL to render into a surface.
  • Accepts a user-provided Renderer object that does the actual rendering.
  • Renders on a dedicated thread to decouple rendering performance from the UI thread.
  • Supports both on-demand and continuous rendering.
  • Optionally wraps, traces, and/or error-checks the renderer's OpenGL calls.

总结

除了上述区别外,SurfaceView通用性更好,GLSurfaceView渲染更细腻,如果想让普通的SurfaceView渲染效果更好,可以加抗锯齿效果,不过抗锯齿效果会有一定的性能消耗,硬解码设置surface模式的话,直接用普通的SurfaceView。

一般兼容性比较好的播放器,会同时支持SurfaceView和GLSurfaceView两种模式供用户根据实际场景选择,以大牛直播SDK(Github)的Android平台RTSP和RTMP播放端为例:

    /* Create rendering */private boolean CreateView() {if (sSurfaceView == null) {Log.i(TAG, "CreateView..");String manufacturer = Build.MANUFACTURER;Log.i(TAG, "CreateView, current manufacturer: " + manufacturer);if (is_enable_hardware_render_mode) {//hardware render模式,第二个参数设置为falsesSurfaceView = NTRenderer.CreateRenderer(this, false);} else {//这个字符串可以自己定义,例如判断华为就填写huawei,魅族就填写meizuif ("huawei".equalsIgnoreCase(manufacturer)) {sSurfaceView = NTRenderer.CreateRenderer(this, true);} else {/** useOpenGLES2: If with true: Check if system supports openGLES, if* supported, it will choose openGLES. If with false: it will set* with default surfaceView;*/sSurfaceView = NTRenderer.CreateRenderer(this, true);}}}if (sSurfaceView == null) {Log.i(TAG, "Create render failed..");return false;}if (is_enable_hardware_render_mode) {SurfaceHolder surfaceHolder = sSurfaceView.getHolder();if (surfaceHolder == null) {Log.e(TAG, "CreateView, surfaceHolder with null..");}surfaceHolder.addCallback(this);}return true;}

感兴趣的开发者可以参考官方文档。

Android播放器之SurfaceView与GLSurfaceView相关推荐

  1. Android 播放器之流媒体,边下边播如此简单。

    闲来无事,想搞一个流媒体开发案例.也答应朋友们奉上博客一枚.历时一周时间,终于摸出点门路了.在此给大家分享一下. 首先要明确的概念:什么是流媒体?转载请注明出处http://blog.csdn.net ...

  2. Android开源音乐播放器之播放器基本功能

    系列文章 Android开源在线音乐播放器--波尼音乐 Android开源音乐播放器之播放器基本功能 Android开源音乐播放器之高仿云音乐黑胶唱片 Android开源音乐播放器之自动滚动歌词 An ...

  3. android音乐播放器之歌词下载、处理、开始、同步

    android音乐播放器之歌词下载.处理.开始.同步 ** 程序源代码在底部 ** 先来看看效果 下载 /*** 自定义下载方法,调用系统DownloadManager下载* * @param myU ...

  4. android音乐播放器之----天天动听

    下载手机软件的时候,随意的下了个天天动听,觉得喜欢,就仿照着他的UI做了个简单的音乐播放器,还不完善,只是在工作之余随便做做,贴图: 本文来自CSDN丹丹博库,转载请必须注明出处: http://bl ...

  5. 【android】音乐播放器之设计思路

    学习Android有一个多月,看完了<第一行代码>以及mars老师的第一期视频通过音乐播放器小项目加深对知识点的理解.从本文开始,将详细的介绍简单仿多米音乐播放器的实现,以及网络解析数据获 ...

  6. 【android】音乐播放器之数据存储总结

    学习Android有一个多月,看完了<第一行代码>以及mars老师的第一期视频通过音乐播放器小项目加深对知识点的理解.从本文开始,将详细的介绍简单仿多米音乐播放器的实现,以及网络解析数据获 ...

  7. 【android】音乐播放器之service服务设计

    学习Android有一个多月,看完了<第一行代码>以及mars老师的第一期视频通过音乐播放器小项目加深对知识点的理解.从本文开始,将详细的介绍简单仿多米音乐播放器的实现,以及网络解析数据获 ...

  8. 【android】音乐播放器之UI设计的点点滴滴

    学习Android有一个多月,看完了<第一行代码>以及mars老师的第一期视频通过音乐播放器小项目加深对知识点的理解.从本文开始,将详细的介绍简单仿多米音乐播放器的实现,以及网络解析数据获 ...

  9. android 车载控制手机音乐播放器,【图】浅谈车载音响播放器之安卓篇

    汽车音响无疑占据着开车乐趣个部分,无论你音乐发烧友与否,陶冶灵魂玩意我想有人去抗拒它,因为毕竟它个美东西,今天本人拿些玩音乐小心跟大家分享,欢迎交流探讨,相互学习! 抛开那 ...

最新文章

  1. linux中html的图片显示不出来,如何在HTML中显示原始的rgb图像
  2. react native的学习
  3. 《过早退出是一切失败的根源》读后感
  4. python 绘图 hist bin参数_Python-hist,distplot bin宽度不一致问题的解决方案
  5. gcc编译ceres-solver报错‘is_trivially_default_constructible’ is not a member of ‘std’
  6. mPaaS小程序创建
  7. 怎么单凭手机进行低成本制作网页?今日让我分享一下经验
  8. 最基础的股市定律--支撑阻挡定律
  9. 归零的心态,做好团队回顾
  10. 石头机器人拖地水量调节_用石头扫地机器人扫地拖地是一种什么体验
  11. 谷歌招聘 变态15题你会做几道?
  12. 【嵌入式AI】TFLite介绍
  13. 会声会影浪漫婚礼视频——美到想哭
  14. Exceptions In Java
  15. ECC的“点加”和“点乘”
  16. iPhone手机忘记了ID账号密码怎么办
  17. Photoshop系列_02简单制作一份海报
  18. Windows 下 C++ 利用 OpenCV glob 函数获取文件夹下所有文件绝对路径
  19. 电商网站业务流程图示例
  20. 牛牛面试题(八股文背诵版)背诵好了Offer在手

热门文章

  1. 明年新iphone使用增强版5nm芯片_苹果A15芯片或将采用台积电5nm+工艺!性能提升极强...
  2. python绘制星空_用python画星空源代码是什么?
  3. delphi bmp绘制矢量文件效率慢_聊一聊矢量瓦片的常识
  4. mysql 重置密码语音_数字语音信号处理学习笔记语音信号的同态处理(2)
  5. 休眠后gpio状态_STM32中GPIO的8种工作模式总结
  6. Java BigDecimal min()方法与示例
  7. java字符串最长回文串_Java中的字符串回文程序
  8. Java中List和Map接口之间的区别
  9. 如何卸载非linux系统分区,如何卸载Linux系统分区?卸载Linux系统分区的方法-站长资讯中心...
  10. android webview 监听js,Android webview与js的数据交互