Reprinted with an indication of the source: http://www.voidcn.com/article/p-ktvazhms-cb.html
We know that android draws the UI in It is done in the main thread, but for some interactions such as camera function or game development, it needs to respond to user input in a timely manner. Obviously, it is not ideal to do UI drawing in the main thread. On the one hand, it will lead to complicated UI drawing. Stuttering or inability to respond to user input in a timely manner affects the user experience. On the other hand, it is easy to cause the main thread to block and cause ANR.
The internal double buffering mechanism of SurfaceView solves this problem very well. Specifically, the main thread is used to display the UI and the rendering thread to draw the UI. The two threads alternate, so that the efficiency of the two threads display interface is very fast. , Of course, the overhead of memory and cpu is also very large.
A simple indication of the thread is as follows
A Load data display interface
B Display interface load data< /pre> extends View
java.lang.Object
android.view.View
android.view.SurfaceView
From the inheritance relationship, it can be seen that SurfaceView is still View Let’s take a look at how the SurfaceView is described in Google’s official documentation. Important sentences are marked in red.
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 surfaceCreated(SurfaceHolder) and 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 w hile it is valid – between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().
Translation into Chinese is as follows:
SurfaceView is an inherited class of View , This view embeds a Surface dedicated to drawing. 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, which can be obtained by the getHolder() method.
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 the rendering thread accesses a legal and valid surface .
By understanding the SurfaceView API, we can find:
core class
1 SurfaceView display Screen
2 SurfaceHolder display content
3 Thread drawing task (rendering thread)
Two conditions need to be met 1. Created after surfaceCreated , Destroy in surfaceDestroyed
Summary
1. SurfaceHolder here can be obtained through getHolder, surfaceCreated and surfaceDestroyed can be The SurfaceHolder.Callback callback is obtained by adding, but it must be noted here that holder.addCallback(this) is added in the construction method; so that SurfaceHolder.Callback can be registered, so that the two methods of surfaceCreated and surfaceDestroyed will be effective.
2. The rendering thread here must
perform drawing tasks between surfaceCreated and surfaceDestroyed.
3. In order to ensure the safety of the thread, generally lock the canvas before drawing Canvas lockCanvas = holder.lockCanvas(); After the drawing is completed, unlock the canvas and submit holder.unlockCanvasAndPost(lockCanvas);// Unlock the canvas and submit the above code will have no effect if it is not executed.
4. Since drawing rendering has layers, it usually draws while (true) in the run method of the rendering thread.
According to the summary of the above points, the typical SurfaceView code template is as follows
//SurfaceHolder.addCallBack(SurfaceHolder.Callback) public for SurfaceHolder.Callback to take effect class UIView extends SurfaceView implements SurfaceHolder .Callback {private RenderThread renderThread;private boolean flag;// Thread running flagprivate SurfaceHolder holder;public UIView(Context context) {super(context);holder = getHolder();holder.addCallback(this); / / Guarantee surfaceCreated, surfaceChanged, surfaceDestroyed// effective}private class RenderThread extends < span class="hljs-title">Thread {@Overridepublic void run() {while (flag ) {try {long startTime = System.currentTimeMillis();drawUI();long endTime=System.currentTimeMillis();long dTime=endTime-startTime; / /Time to draw onceint fps=(int) (1000/dTime ); // The number of frames that can be drawn in 1 second>30 System.out.println(fps);} catch (Exception e) {e.printStackTrace();}}}}// drawpublic void drawUI() {// lock the canvas span>Canvas lockCanvas = holder.lockCanvas();// // Drawing interfacePaint paint = new Paint ();// Paintbrush //TODO //Execute Drawing rendering //......// Unlock the canvas and submit holder. unlockCanvasAndPost(lockCanvas);// Unlock the canvas and submit. If you don’t execute it, the above code will have no effect}// When Surf Called when ace is created@Overridepublic void surfaceCreated(SurfaceHolder holder) {Log.d("TAG", "surfaceCreated");renderThread = new RenderThread();flag = true ;renderThread.start();// The thread is started...}// When the Surface is destroyed When calling@Overridepublic void span> surfaceDestroyed(SurfaceHolder holder) {Log.d("TAG", "surfaceDestroyed");// Generally stop threads are loops of control threadsflag = false;}// Called when the Surface changes @Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {Log.d("TAG", "surfaceChanged");}/** * Process screen click events* * @param event */public void handleTouch span>(MotionEvent event) {switch (event.getAction()) {//case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_DOWN: // When pressing When downloadingb reak;case MotionEvent.ACTION_UP:default:break;}}
This is the end of the core analysis. Below, through the above analysis process, use SurfaceView to implement a hello display demo. Others can directly apply this template in complex UI drawing. Just implement your own drawUI. The code comments are very detailed, so I won't repeat them here. Those who are interested can download the research, code download path.
Click to download the source code http://download.csdn.net/detail/pangrui201/9458648
Reprinted and noted Source: http://www.voidcn.com/article/p-ktvazhms-cb.html
We know that android draws the UI in the main thread, but for some interactive features such as camera function or Game development and other needs need to respond to user input in a timely manner. Obviously, it is not ideal to do UI drawing in the main thread. On the one hand, it will cause complicated UI drawing to freeze or user input cannot respond in time and affect the user experience. On the other hand, it is easy The main thread is blocked and ANR occurs.
The internal double buffering mechanism of SurfaceView solves this problem very well. Specifically, the main thread is used to display the UI and the rendering thread to draw the UI. The two threads alternate, so that the efficiency of the two threads display interface is very fast. , Of course, the overhead of memory and cpu is also very large.
A simple indication of the thread is as follows
A Load data display interface
B Display interface load data< /pre> extends View
java.lang.Object
android.view.View
android.view.SurfaceView
From the inheritance relationship, it can be seen that SurfaceView is still View Let’s take a look at how the SurfaceView is described in Google’s official documentation. Important sentences are marked in red.
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 surfaceCreated(SurfaceHolder) and 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 wh ile it is valid – between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().
Translation into Chinese is as follows:
SurfaceView is an inherited class of View , This view embeds a Surface dedicated to drawing. 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, which can be obtained by the getHolder() method.
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 the rendering thread accesses a legal and valid surface .
By understanding the SurfaceView API, we can find:
core class
1 SurfaceView display Screen
2 SurfaceHolder display content
3 Thread drawing task (rendering thread)
Two conditions need to be met 1. Created after surfaceCreated , Destroy in surfaceDestroyed
Summary
1. SurfaceHolder here can be obtained through getHolder, surfaceCreated and surfaceDestroyed can be The SurfaceHolder.Callback callback is obtained by adding, but it must be noted here that holder.addCallback(this) is added in the construction method; so that SurfaceHolder.Callback can be registered, so that the two methods of surfaceCreated and surfaceDestroyed will be effective.
2. The rendering thread here must
perform drawing tasks between surfaceCreated and surfaceDestroyed.
3. In order to ensure the safety of the thread, generally lock the canvas before drawing Canvas lockCanvas = holder.lockCanvas(); After the drawing is completed, unlock the canvas and submit holder.unlockCanvasAndPost(lockCanvas);// Unlock the canvas and submit the above code will have no effect if it is not executed.
4. Since drawing rendering has layers, it usually draws while (true) in the run method of the rendering thread.
According to the summary of the above points, the typical SurfaceView code template is as follows
//SurfaceHolder.addCallBack(SurfaceHolder.Callback) public for SurfaceHolder.Callback to take effect class UIView extends SurfaceView implements SurfaceHolder .Callback {private RenderThread renderThread;private boolean flag;// Thread running flagprivate SurfaceHolder holder;public UIView(Context context) {super(context);holder = getHolder();holder.addCallback(this); // Ensure surfaceCreated, surfaceChanged, surfaceDestroyed// effective}private class RenderThread extends Thread {@Overridepublic < span class="hljs-keyword">void run() {while (flag) {try {long startTime = System.currentTimeMillis();drawUI();long endTime=System.currentTimeMillis();long dTime=endTime-startTime; // Draw onceint fps=(int) (1000/dTime ); // The number of frames that can be drawn in 1 second>30 System.out.println(fps);} catch (Exception e) {e.printStackTrace();}}}}// drawpublic void drawUI() {// lock the canvas span>Canvas lockCanvas = holder.lockCanvas();// // Drawing interfacePaint paint = new Paint ();// Paintbrush //TODO //Execute Drawing rendering //......// Unlock the canvas and submit holder. unlockCanvasAndPost(lockCanvas);// Unlock the canvas and submit. If not executed, the above code will have no effect}// When Surfac e is called when creating@Overridepublic void surfaceCreated(SurfaceHolder holder) {Log.d("TAG", "surfaceCreated");renderThread = new RenderThread();flag = true ;renderThread.start();// The thread is started...}// When the Surface is destroyed When calling@Overridepublic void span> surfaceDestroyed(SurfaceHolder holder) {Log.d("TAG", "surfaceDestroyed");// Generally stop threads are loops of control threadsflag = false;}// Called when Surface changes span>@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width ,int height) {Log.d("TAG", "surfaceChanged");}/** * Process screen click events* * @param event * /public void handleTouch (MotionEvent event) {switch (event.getAction()) {//case MotionEvent.ACTION_MOVE:< span class="hljs-keyword">break;case MotionEvent.ACTION_DOWN: // When pressed Timebre ak;case MotionEvent.ACTION_UP:default:break;}}
This is the end of the core analysis. Below, through the above analysis process, use SurfaceView to implement a hello display demo. Others can directly apply this template to complex UI drawing. Just implement your own drawUI. The code comments are very detailed, so I won't repeat them here. Those who are interested can download the research, code download path.
Click to download source code http://download.csdn.net/detail/pangrui201/9458648