问题描述
我正在努力理解绘制到 SurfaceView
的过程以及整个 Surface
/Canvas
/Bitmap系统,在Android中使用.
I'm struggling to understand the process of drawing to
SurfaceView
and therefore the whole Surface
/Canvas
/Bitmap
system, which is used in Android.
我已经阅读了所有文章和 API 文档页面,我可以在 android-developers 站点上找到这些页面、一些 android 图形教程、LunarLander 源代码和 这个问题.
I've read all articles and API documentation pages, which I was able to find on android-developers site, a few tutorials of android graphics, LunarLander source code and this question.
请告诉我,这些陈述哪些是正确的,哪些不是,以及为什么.
Please tell me, which of these statements are true, which are not, and why.
Canvas
附有自己的Bitmap
.Surface
附有自己的Canvas
.窗口的所有
View
共享相同的Surface
,因此共享相同的Canvas
.SurfaceView
是View
的子类,与其他View
的子类和View
本身不同,它具有它自己的Surface
用于绘制.
Canvas
has its ownBitmap
attached to it.Surface
has its ownCanvas
attached to it.All
View
's of window share the sameSurface
and thus share the sameCanvas
.SurfaceView
is subclass ofView
, which, unlike otherView
's subclasses andView
itself, has its ownSurface
to draw in.
还有一个问题:
如果已经有一个
Canvas
用于位图的高级操作,为什么还需要Surface
类.举例说明Canvas
不适合做Surface
可以做的工作.
Why is there a need for a
Surface
class, if there is already aCanvas
for high-level operations with bitmap. Give an example of a situation whereCanvas
is non-suitable for doing work whichSurface
can do.
推荐答案
以下是一些定义:
Surface 是一个包含正在合成到屏幕上的像素的对象.你在屏幕上看到的每个窗口(一个对话框、你的全屏活动、状态栏)都有它自己的绘制表面,Surface Flinger 以正确的 Z 顺序将这些渲染到最终显示.一个表面通常有多个缓冲区(通常是两个)来进行双缓冲渲染:当 Surface Flinger 使用最后一个缓冲区合成屏幕时,应用程序可以绘制其下一个 UI 状态,而无需等待应用程序完成绘图.
A Surface is an object holding pixels that are being composited to the screen. Every window you see on the screen (a dialog, your full-screen activity, the status bar) has its own surface that it draws in to, and Surface Flinger renders these to the final display in their correct Z-order. A surface typically has more than one buffer (usually two) to do double-buffered rendering: the application can be drawing its next UI state while the surface flinger is compositing the screen using the last buffer, without needing to wait for the application to finish drawing.
窗口基本上就像您想象的桌面上的窗口一样.它有一个单一的表面,窗口的内容在其中呈现.应用程序与窗口管理器交互以创建窗口;窗口管理器为每个窗口创建一个 Surface 并将其提供给应用程序进行绘图.应用程序可以在 Surface 中绘制任何它想要的东西;对于窗口管理器,它只是一个不透明的矩形.
A window is basically like you think of a window on the desktop. It has a single Surface in which the contents of the window is rendered. An application interacts with the Window Manager to create windows; the Window Manager creates a Surface for each window and gives it to the application for drawing. The application can draw whatever it wants in the Surface; to the Window Manager it is just an opaque rectangle.
视图是窗口内的交互式 UI 元素.一个窗口有一个附加的视图层次结构,它提供了窗口的所有行为.每当窗口需要重绘时(例如因为视图使自身无效),这将在窗口的 Surface 中完成.Surface 被锁定,它返回一个 Canvas 可以用来绘制它.绘制遍历在层次结构中完成,为每个视图传递 Canvas 以绘制其 UI 部分.完成后,Surface 将被解锁并发布,以便将刚刚绘制的缓冲区交换到前台,然后由 Surface Flinger 合成到屏幕.
A View is an interactive UI element inside of a window. A window has a single view hierarchy attached to it, which provides all of the behavior of the window. Whenever the window needs to be redrawn (such as because a view has invalidated itself), this is done into the window's Surface. The Surface is locked, which returns a Canvas that can be used to draw into it. A draw traversal is done down the hierarchy, handing the Canvas down for each view to draw its part of the UI. Once done, the Surface is unlocked and posted so that the just drawn buffer is swapped to the foreground to then be composited to the screen by Surface Flinger.
SurfaceView 是 View 的一种特殊实现,它还创建了自己的专用 Surface,供应用程序直接绘制(在普通视图层次结构之外,否则必须共享窗口的单个 Surface).它的工作方式比你想象的要简单——SurfaceView 所做的就是要求窗口管理器创建一个新窗口,告诉它在 SurfaceView 窗口的后面或前面对该窗口进行 Z 排序,并将其定位以匹配SurfaceView 出现在包含窗口中的位置.如果表面被放置在主窗口后面(按 Z 顺序),SurfaceView 还会用透明度填充主窗口的部分,以便可以看到表面.
A SurfaceView is a special implementation of View that also creates its own dedicated Surface for the application to directly draw into (outside of the normal view hierarchy, which otherwise must share the single Surface for the window). The way this works is simpler than you may expect -- all SurfaceView does is ask the window manager to create a new window, telling it to Z-order that window either immediately behind or in front of the SurfaceView's window, and positioning it to match where the SurfaceView appears in the containing window. If the surface is being placed behind the main window (in Z order), SurfaceView also fills its part of the main window with transparency so that the surface can be seen.
位图只是一些像素数据的接口.当您直接创建一个像素时,这些像素可能由 Bitmap 本身分配,或者它可能指向它不拥有的像素,例如内部发生的将 Canvas 连接到 Surface 以进行绘制的情况.(创建一个 Bitmap 并指向 Surface 的当前绘图缓冲区.)
A Bitmap is just an interface to some pixel data. The pixels may be allocated by Bitmap itself when you are directly creating one, or it may be pointing to pixels it doesn't own such as what internally happens to hook a Canvas up to a Surface for drawing. (A Bitmap is created and pointed to the current drawing buffer of the Surface.)
另外请记住,正如这所暗示的,SurfaceView 是一个非常重的对象.如果你在一个特定的 UI 中有多个 SurfaceView,停下来想想这是否真的需要.如果你有两个以上,你几乎肯定有太多了.
Also please keep in mind that, as this implies, a SurfaceView is a pretty heavy-weight object. If you have multiple SurfaceViews in a particular UI, stop and think about whether this is really needed. If you have more than two, you almost certainly have too many.
这篇关于理解画布和表面概念的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!