Introduction and application of SurfaceView

Returned from http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

Author: Juner’s Blog

First, let’s take a look at the official API’s introduction to SurfaceView

< p>SurfaceView’s API introduction

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.

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.< /span>

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().
Corresponding Chinese translation
SurfaceView is an inherited class of View. A Surface dedicated to drawing is embedded in this view. You can control the format and size of this Surface. Surfaceview controls the drawing position of this Surface.
The surface is Z-ordered, which means that it is always behind the window where it is. Surfaceview provides a visible area, only the part of the surface in this visible area is visible, and the part outside the visible area is not visible. The layout of the surface is affected by the hierarchical relationship of the views, and its sibling view nodes will be displayed at the top. This means that the content of the surface will be obscured by its sibling views. This feature can be used to place overlays (for example, controls such as text and buttons). Note that if there are transparent controls on the surface, then every change of it will cause the framework to recalculate the transparency effects of it and the top-level controls, which will affect performance.
You can access this surface through the SurfaceHolder interface, and the getHolder() method can get this interface.
When the surfaceview becomes visible, the surface is created; before the surfaceview is hidden, the surface is destroyed. This saves resources. If you want to see when the surface is created and destroyed, you can override surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder).
The core of surfaceview is to provide two threads: UI thread and rendering thread. It should be noted here:
1> All SurfaceView and SurfaceHolder.Callback methods should be called in the UI thread, which is generally the main thread of the application. Various variables to be accessed by the rendering thread should be synchronized.
2> Since the surface may be destroyed, it is only valid between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed(), so make sure that what the rendering thread accesses is legal and valid Surface.

Next, talk about my understanding of it
1, definition< /p>

can directly obtain image data from hardware interfaces such as memory or DMA, and is a very important drawing container.

Its feature is that it can draw on the screen in a thread other than the main thread. This can avoid blocking the main thread when the drawing task is heavy, thereby improving the response speed of the program. SurfaceView is often used in game development, and the background, characters, animation, etc. in the game are drawn on the canvas as much as possible.

2, implementation

First inherit SurfaceView and implement SurfaceHolder.Callback interface
The reason for using the interface: Because there is a principle in using SurfaceView, all drawing work must be started after the Surface is created (Surface—surface, this concept is often mentioned in graphics programming. Basically we can use it as video memory A mapping of, the content written to the Surface
can be copied directly to the video memory to be displayed, which makes the display speed very fast), and it must end before the Surface is destroyed. So surfaceCreated and surfaceDestroyed in Callback become the boundary of drawing processing code.

Methods to be rewritten

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

 / /Fired when the size of the surface changes

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

 //It is triggered when it is created, and the drawing thread is usually called here.

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

 //It is fired when it is destroyed. Generally, the drawing thread is stopped and released here.

The whole process: inherit SurfaceView and implement SurfaceHolder.Callback interface —-> SurfaceView.getHolder() gets SurfaceHolder object—->SurfaceHolder.addCallback(callback) add a callback function—->SurfaceHolder.lockCanvas() get the Canvas object and lock the canvas—->Canvas painting—->SurfaceHolder.unlockCanvasAndPost (Canvas canvas) Finish locking the drawing, submit the changes, and display the graphics.

3, SurfaceHolder
A class SurfaceHolder is used here, which can be regarded as The surface controller is used to manipulate the surface. Process the effects and animations drawn on its Canvas, control the surface, size, pixels, etc.
Several methods that need attention:
(1), abstract void addCallback(SurfaceHolder.Callback callback);
// Give the current holder of the SurfaceView a callback object.
(2), abstract Canvas lockCanvas();
// Lock the canvas, generally after locking, you can use the returned canvas object Canvas, in Draw pictures and other operations on it.
(3), abstract Canvas lockCanvas(Rect dirty);
// Lock a certain area of ​​the canvas for drawing, etc.. Because after drawing the picture , The following unlockCanvasAndPost will be called to change the display content.
// Compared with some games with high memory requirements, it is not necessary to redraw pixels in other areas except dirty, which can increase the speed.
(4), abstract void unlockCanvasAndPost(Canvas canvas);
// End the lock drawing and submit the changes.
4. Example

The example here implements a rectangle and a timer

View Code

 1 View Code

2 package xl.test;
3
4 import android.app .Activity;
5 import android.content.Context;
6 import android.graphics.Canvas;
7 import android.graphics.Color;
8 import android.graphics.Paint;
9 import android.graphics.Rect;
10 import android.os.Bundle;
11 import android.view.SurfaceHolder;
12 import android.view.SurfaceView;
13
14 public class span> ViewTest extends Activity {
15 /** Called when the activity is first created. */
16 @Override
17 public void onCreate(Bundle savedInstanceState) {
18 super.onCreate(savedInstanceState);
19 setContentView(new MyView(this));
20 }
21 //View inner class
22 class MyView extends< /span> SurfaceView implements SurfaceHolder.Callback
23 {
24 private SurfaceHolder holder;
25 private MyThread myThread;
26 public MyView(Context context) {
27 super(context);
28 // TODO Auto-generated constructor stub
29 holder = this. getHolder();
30 holder.addCallback(this);
31 myThread = new MyThread(holder);//Create a drawing thread
32 }
33
34 @Override
35 public void surfaceChanged(SurfaceHolder holder, int format, int width,
36 int height) {
37 // TODO Auto-generated method stub
38
39 }
40
41 @Override
42 public void surfaceCreated(SurfaceHolder holder) {
43 // TODO Auto-generated method stub
44 myThread.isRun = true;
45 myThread.start();
46 }
47
48 @Override
49 public void surfaceDestroyed(SurfaceHolder holder) {
50 // TODO Auto-generated method stub
51 myThread.isRun = false;
52 }
53
54 }
55 //Thread inner class
56 class MyThread extends< /span> Thread
57 {
58 private SurfaceHolder holder;
59 public boolean isRun;
60 public MyThread(SurfaceHolder holder)
61 {
62 this.holder =holder;
63 isRun = true;
64 }
65 @Override
66 public void run()
67 {
68 int count = 0;
69 while(isRun)
70 {
71 Canvas c = null;
72 try
73 {
74 synchronized (holder)
75 {
76 c = holder.lockCanvas();//< span style="color:#008000">Lock the canvas. Generally, after locking, you can use the returned canvas object Canvas to draw pictures on it.

77 c.drawColor(Color.BLACK);//Set the canvas background color
78 Paint p = new Paint(); //Create a brush
79 p.setColor(Color.WHITE);
80 Rect r = new Rect(100, 50, 300 , 250);
81 c.drawRect(r, p);
82 c.drawText("This is the first"+(count++)+"second", 100, 310, p);
83 Thread.sleep(1000);//Sleep time is 1 second
84 }
85 }
86 catch (Exception e) {
87 // TODO: handle exception
88 e.printStackTrace();
89 }
90 finally
91 {
92 if(c!= null)
93 {
94 holder.unlockCanvasAndPost(c);//End locking the drawing and submit the changes.
95
96 }
97 }
98 }
99 }
100 }
101 }

Note:myThread = new MyThread(holder); This sentence should be written in the surfaceCreated method, so that you can avoid BUG when you click the HOME button and go back, because you click HOME When the key is pressed, the construction method of MyView is not executed, and the thread is wrong~

View Code

 1 View Code

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

  1 View Code 

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

Leave a Comment

Your email address will not be published.