Android-View、SurfaceView、GLSurfaceView的区别认识

老规矩,看看官方定义

View | Android Developers

SurfaceView | Android Developers

GLSurfaceView | Android Developers

View定义

public class View 
extends Object implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource

java.lang.Object
   ↳    android.view.View
Known direct subclasses
AnalogClock, ImageView, KeyboardView, MediaRouteButton, ProgressBar, Space, SurfaceView, TextView, TextureView, ViewGroup, ViewStub
Known indirect subclasses
AbsListView, AbsSeekBar, AbsSpinner, AbsoluteLayout, ActionMenuView, AdapterView<T extends Adapter>, AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView, Button, CalendarView, and 52 others.

This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.      

翻译:继承自Object, 直接继承或者间接继承该View的相关了有Textview, Recyclview,ViewGroup等。基本上组合控件大多都是继承ViewGroup(间接的就继承了View). 该View占据了屏幕的一块矩形区域以及负责绘制和事件的处理。它是所有控件的基类,用于创建UI组件(像buttons, 文本区域等)。之后就是View的很多方法,如何定义View的一些介绍。之前我们学习自定义View也有所了解了。自定义控件的水还是蛮深的。

绘制刷新是属于被动绘制刷新,只能在主线程中做刷新操作。一般我们需要刷新都需要invalidate();一下。

SurfaceView的定义

public class SurfaceView 
extends View 

java.lang.Object
   ↳    android.view.View
       ↳    android.view.SurfaceView
Known direct subclasses
GLSurfaceView, VideoView

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(SurfaceHolder) and SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder) 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().
Note: Starting in platform version Build.VERSION_CODES.N, SurfaceView's window position is updated synchronously with other View rendering. This means that translating and scaling a SurfaceView on screen will not cause rendering artifacts. Such artifacts may occur on previous versions of the platform when its window is positioned asynchronously.

翻译: SurfaceView继承自View,并提供了一个可以嵌入到View结构树中的独立的绘图层,你可以完全控制这个绘图层,比如说设定它的大小。SurfaceView负责将surface放置在屏幕上的正确位置。 这个Surface的Z轴方向允许窗体在它后面持有该SurfaceView,就是在窗体上打了个洞允许surface显示。由于视图的相互置顶重叠,就会发生绘制混合(就是alpha混合处理), 这对性能有影响。如果在SurfaceView上面绘制一个姊妹控件,有可能不能正确混合。

可以通过getHolder()获取SurfaceHolder - Return the SurfaceHolder providing access and control over this SurfaceView's underlying surface.

Abstract interface to someone holding a display surface. Allows you to control the surface size and format, edit the pixels in the surface, and monitor changes to the surface. This interface is typically available through the SurfaceView class.

When using this interface from a thread other than the one running its SurfaceView, you will want to carefully read the methods lockCanvas() and Callback.surfaceCreated().

顾名思义就是Surface的持有者,SurfaceView就是通过过SurfaceHolder来对Surface进行管理控制的。比如控件大小, 格式,编辑像素,以及监视其变化。通过SurfaceView可以获取该接口。

当窗体显示时你需要实现SurfaceHolder.Callback.surfaceCreated(SurfaceHolder), 当窗体隐藏后需要实现SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder)。分别处理surface的创建和销毁。

用SurfaceView的一个主要目的是为了开启第二个线程去在片屏幕上做渲染。如果你打算这样做,你需要遵循一些语法:

1. 所有的SurfaceView and[SurfaceHolder.Callback](https://link.zhihu.com/?target=https%3A//developer.android.google.cn/reference/android/view/SurfaceHolder.Callback.html%3Fhl%3Dzh-cn)回调都是在窗体的主线程中调用。因此我们需要处理好这些回调与绘制的同步。

2. 你必须要保证绘制线程可用。 在 [SurfaceHolder.Callback.surfaceCreated()](https://link.zhihu.com/?target=https%3A//developer.android.google.cn/reference/android/view/SurfaceHolder.Callback.html%3Fhl%3Dzh-cn%23surfaceCreated%28android.view.SurfaceHolder%29)and[SurfaceHolder.Callback.surfaceDestroyed()](https://link.zhihu.com/?target=https%3A//developer.android.google.cn/reference/android/view/SurfaceHolder.Callback.html%3Fhl%3Dzh-cn%23surfaceDestroyed%28android.view.SurfaceHolder%29)之间才能调用。

注意: 从Android 版本<u style="text-decoration: none; border-bottom: 1px dashed grey;">[Build.VERSION_CODES.N](https://link.zhihu.com/?target=https%3A//developer.android.google.cn/reference/android/os/Build.VERSION_CODES.html%3Fhl%3Dzh-cn%23N)</u>, 开始, SurfaceView的窗口位置与其他视图呈现同步更新, 这意味着平移缩放不会有rendering artifacts问题了。而早期的版本则会产生rendering artifacts的问题. rendering artifacts - 渲染伪影(百度翻译),小白理解就是如果不处理好同步的问题,可能就是产生画面花,比如按钮画了一半,又去画文本,然后又交叉,就会删除渲染花的问题。 小白还是不太懂。

SurfaceView - 后面需要实践下如何正确使用。争取多实践下....

1. 不过从上面看主要的特点就是可以新开一个线程用作绘制,进而避免必须在主线程中做长时间UI更新导致的卡顿甚至ANR的问题。

2. 新开一个线程做绘制除了避免阻塞UI线程,还能提供“主动刷新”,可以不停的进行绘制(比如人在不停的跑)更新。 这样想动画也可以做了哈。Animation相关动画类是不是也是这样呢(值得研究)?或者某些情况下,surfaceview能更好的掌控和优化动画性能。

3. 2D游戏说,就你了,来试试...

GLSurfaceView的定义

public class GLSurfaceView 
extends SurfaceView implements SurfaceHolder.Callback2

java.lang.Object
   ↳    android.view.View
       ↳    android.view.SurfaceView
           ↳    android.opengl.GLSurfaceView

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,Google又扩展了GLSurfaceView, 专门用于OpenGL rendering使用。OpenGL哟。【 对这个感兴趣的可以了解下OpenGL的相关知识。小白刚开始工作是做的地图,当时就是OpenGL封装的底层渲染引擎(采用c语言,结合了cairo(开罗2d绘制引擎库))。所以小白还是有一定了解。 同时第二份工作就是Android 3D做三维模型建模(OpenGL es2.0+的版本),处理起来很麻烦,性能也不太行,后面才采用了U3D引擎(引擎性能上,渲染,手势等什么的处理的比较好),顺带提下哈】。

GLSurfaceView提供了如下特性:

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

感觉很骚的样子。GPU渲染你不得不服,就是快。基本上3D就是它了。如果要做纯Android 3D的小游戏,重点关注下这个GLSurfaceView

GLSurfaceView- 后面需要实践下如何正确使用。

image

官方基本介绍就是上面,当然每个还有很多知识点。我们先了解基本的介绍吧,后面可以先直接做个实践,加深下基本理解,给自己一个提前的研究指导,一旦有更多时间和经历就应该深入扩展学习了哟!

网上有很多解释,有些已经过时,不过可以了解下,了解自己想了解的就行:

QT3D | IT自习室 - 小白早期的学习记录(Qt平台实践)

VBO、FBO、PBO 学习总结贴 (OpenGL ES) - 小白早期的学习记录

Android 视频展示控件之 SurfaceView、GLSurfaceView、SurfaceTexture、TextureView 对比总结

Android中View,SurfaceView和GLSurfaceView绘图的区别 - doom20082004的博客 - CSDN博客

Android GLSurfaceView详解

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容