Android之SurfaceView学习

首先咱们先来看下官方API对SurfaceView的介绍 android

SurfaceView的API介绍 编程

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 canvas

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. app

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 surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden. ide

One of the purposes of this class is to provide a surface in which a secondary thread can render in to 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().
对应的中文翻译
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你能够控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
surface是纵深排序(Z-ordered)的,这代表它总在本身所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部份内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性能够用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,若是surface上面 有透明控件,那么它的每次变化都会引发框架从新计算它和顶层控件的透明效果,这会影响性能。
你能够经过SurfaceHolder接口访问这个surface,getHolder()方法能够获得这个接口。
surfaceview变得可见时,surface被建立;surfaceview隐藏前,surface被销毁。这样能节省资源。若是你要查看 surface被建立和销毁的时机,能够重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。
surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:
1> 全部SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,通常来讲就是应用程序主线程。渲染线程所要访问的各类变量应该做同步处理。
2> 因为surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,因此要确保渲染线程访问的是合法有效的surface。 性能

接下来呢,说说本身对它的理解
一、定义 动画

能够直接从内存或者DMA等硬件接口取得图像数据,是个很是重要的绘图容器。 this

它的特性是:能够在主线程以外的线程中向屏幕绘图上。这样能够避免画图任务繁重的时候形成主线程阻塞,从而提升了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽可能在画布canvas中画出。

二、实现

首先继承SurfaceView并实现SurfaceHolder.Callback接口
使用接口的缘由:由于使用SurfaceView 有一个原则,全部的绘图工做必须得在Surface 被建立以后才能开始(Surface—表面,这个概念在 图形编程中经常被提到。基本上咱们能够把它看成显存的一个映射,写入到Surface 的内容
能够被直接复制到显存从而显示出来,这使得显示速度会很是快),而在Surface 被销毁以前必须结束。因此Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。

须要重写的方法

 (1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}

  //在surface的大小发生改变时激发

 (2)public void surfaceCreated(SurfaceHolder holder){}

  //在建立时激发,通常在这里调用画图的线程。

 (3)public void surfaceDestroyed(SurfaceHolder holder) {}

  //销毁时激发,通常在这里将画图的线程中止、释放。

整个过程:继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()得到SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()得到Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。


三、SurfaceHolder
这里用到了一个类SurfaceHolder,能够把它当成surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
几个须要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
// 给SurfaceView当前的持有者一个回调对象。
(2)、abstract Canvas lockCanvas();
// 锁定画布,通常在锁定后就能够经过其返回的画布对象Canvas,在其上面画图等操做了。
(3)、abstract Canvas lockCanvas(Rect dirty);
// 锁定画布的某个区域进行画图等..由于画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。
// 相对部份内存要求比较高的游戏来讲,能够不用重画dirty外的其它区域的像素,能够提升速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
// 结束锁定画图,并提交改变。
四、实例

这里的例子实现了一个矩形和一个计时器

View Code
复制代码
1 package xl.test;
2
3 import android.app.Activity;
4 import android.content.Context;
5 import android.graphics.Canvas;
6 import android.graphics.Color;
7 import android.graphics.Paint;
8 import android.graphics.Rect;
9 import android.os.Bundle;
10 import android.view.SurfaceHolder;
11 import android.view.SurfaceView;
12
13 public class ViewTest extends Activity {
14 /** Called when the activity is first created. */
15 @Override
16 public void onCreate(Bundle savedInstanceState) {
17 super .onCreate(savedInstanceState);
18 setContentView( new MyView( this ));
19 }
20 // 视图内部类
21 class MyView extends SurfaceView implements SurfaceHolder.Callback
22 {
23 private SurfaceHolder holder;
24 private MyThread myThread;
25 public MyView(Context context) {
26 super (context);
27 // TODO Auto-generated constructor stub
28 holder = this .getHolder();
29 holder.addCallback( this );
30 myThread = new MyThread(holder); // 建立一个绘图线程
31 }
32
33 @Override
34 public void surfaceChanged(SurfaceHolder holder, int format, int width,
35 int height) {
36 // TODO Auto-generated method stub
37
38 }
39
40 @Override
41 public void surfaceCreated(SurfaceHolder holder) {
42 // TODO Auto-generated method stub
43 myThread.isRun = true ;
44 myThread.start();
45 }
46
47 @Override
48 public void surfaceDestroyed(SurfaceHolder holder) {
49 // TODO Auto-generated method stub
50 myThread.isRun = false ;
51 }
52
53 }
54 // 线程内部类
55 class MyThread extends Thread
56 {
57 private SurfaceHolder holder;
58 public boolean isRun ;
59 public MyThread(SurfaceHolder holder)
60 {
61 this .holder = holder;
62 isRun = true ;
63 }
64 @Override
65 public void run()
66 {
67 int count = 0 ;
68 while (isRun)
69 {
70 Canvas c = null ;
71 try
72 {
73 synchronized (holder)
74 {
75 c = holder.lockCanvas(); // 锁定画布,通常在锁定后就能够经过其返回的画布对象Canvas,在其上面画图等操做了。
76 c.drawColor(Color.BLACK); // 设置画布背景颜色
77 Paint p = new Paint(); // 建立画笔
78 p.setColor(Color.WHITE);
79 Rect r = new Rect( 100 , 50 , 300 , 250 );
80 c.drawRect(r, p);
81 c.drawText( " 这是第 " + (count ++ ) + " " , 100 , 310 , p);
82 Thread.sleep( 1000 ); // 睡眠时间为1秒
83 }
84 }
85 catch (Exception e) {
86 // TODO: handle exception
87 e.printStackTrace();
88 }
89 finally
90 {
91 if (c != null )
92 {
93 holder.unlockCanvasAndPost(c); // 结束锁定画图,并提交改变。
94
95 }
96 }
97 }
98 }
99 }
100 }
相关文章
相关标签/搜索