SurfaceView和View之间的区别?

Vik*_*tor 207 graphics android 2d

什么时候有必要,或者更好地使用SurfaceView而不是View

Nik*_*lin 208

视图全部绘制在同一GUI线程上,该线程也用于所有用户交互.

因此,如果您需要快速更新GUI,或者渲染需要花费太多时间并影响用户体验,那么请使用SurfaceView.

  • 官方详细解答:http://developer.android.com/guide/topics/graphics/2d-graphics.html (4认同)
  • 检查穿孔者的答案,其中包含更多细节. (2认同)

Ral*_*eon 101

我注意到的一些事情:

  • SurfaceViews包含一个很好的渲染机制,允许线程更新表面的内容而不使用处理程序(适用于动画).
  • Surfaceview 不能透明,它们只能出现在视图层次结构中的其他元素后面.
  • 我发现动画要比渲染到视图要快得多.

有关更多信息(以及一个很好的用法示例),请参阅SDK示例部分中的LunarLander项目.

  • 仅供参考...... SurfaceView现在可以透明:http://stackoverflow.com/questions/5391089/how-to-make-surfaceview-transparent (35认同)
  • 时间进展如何! (5认同)

pie*_*fou 76

更新于05/09/2014

好.我们现在正式文件.它以更好的方式谈论了我提到的所有内容.


在这里阅读更详细.

是的,主要的区别是surfaceView可以在后台线程上更新.但是,您可能会关注更多.

  • surfaceView具有专用表面缓冲区,而所有视图共享一个由ViewRoot分配的表面缓冲区.换句话说,surfaceView需要更多资源.

  • surfaceView无法进行硬件加速(从JB4.2开始),而普通View上95%的操作都是使用openGL ES加速硬件加速的.

  • 应该做更多的工作来创建自定义的surfaceView.你需要监听surfaceCreated/Destroy事件,创建一个渲染线程,更重要的是,同步渲染线程和主线程.但是,要自定义视图,您需要做的就是覆盖onDraw方法.

  • 更新时间不同.普通视图更新机制受框架约束或控制:您view.invalidate在UI线程或view.postInvalid其他线程中调用以向框架指示应该更新视图.但是,视图不会立即更新,而是等到下一个VSYNC事件到达.理解VSYNC的简单方法是将其视为一个计时器,在60fps屏幕上每16ms启动一次.在Android中,所有普通视图更新(实际显示但我今天不会说它)与VSYNC同步以获得更好的平滑度.现在,回到surfaceView,您可以随时随地渲染它.但是,我很难说它是否有优势,因为显示器也与VSYNC同步,如前所述.

  • 从你的回答中我感觉最好使用一个派生自View而不是SurfaceView的类.还是我弄错了?这将与大多数2D游戏开发教程相对立. (2认同)
  • @Storm需要考虑的是,SurfaceView设计不应该阻塞UI线程,其中View只能由UI线程修改.对于大多数游戏,SurfaceViews将进行大量渲染,这将通过简单的视图阻止UI线程.从我的理解,这是SurfaceView的主要好处. (2认同)

jco*_*der 44

主要区别在于SurfaceView可以通过背景theads绘制,但Views不能. SurfaceViews虽然使用了更多资源,但除非必须,否则不要使用它们.

  • Surfaceview使用的资源多于视图 (6认同)

Set*_*sak 12

A SurfaceView是Android中的自定义视图,可用于在其中绘制.

a View和a 之间的主要区别在于SurfaceView绘制了一个View UI Thread,用于所有用户交互.

如果您想要足够快地更新UI并在其中呈现大量信息,SurfaceView是更好的选择.

但是有一些技术内容SurfaceView:

1. 它们不是硬件加速的.

2. 当你调用的方法普通视图渲染invalidate或者postInvalidate(),但这并不意味着该视图会立即更新(A VSYNC将被发送,并且操作系统决定何时它被更新.该SurfaceView可以立即更新.

3. 一个SurfaceView有分配surface buffer,所以它更昂贵


som*_*yay 7

surfaceview和view之间的主要区别之一是要刷新普通视图的屏幕,我们必须从定义视图的同一线程调用invalidate方法.但即使我们调用invalidate,刷新也不会立即发生.它仅在下一次到达VSYNC信号后发生.VSYNC信号是内核生成的信号,每16.6 ms发生一次,或者也称为每秒60帧.因此,如果我们想要更多地控制屏幕的刷新(例如对于非常快速移动的动画),我们就不应该使用普通的视图类.

另一方面,在surfaceview的情况下,我们可以按照我们想要的速度刷新屏幕,我们可以从后台线程中完成.因此,faceview的清新真的不依赖于VSYNC,如果我们想要进行高速动画,这非常有用.我很少有培训视频和示例应用程序可以很好地解释所有这些事情.请查看以下培训视频.

https://youtu.be/kRqsoApOr9U

https://youtu.be/Ji84HJ85FIQ

https://youtu.be/U8igPoyrUf8