The so-called double buffering is a task of two threads simultaneously. The game uses double buffering mainly to solve the problem of drawing flickering and improve the drawing efficiency. When surfaceview is used for drawing, the area of the drawing will be locked. That is to say, this area can be used for drawing next time only after the drawing is completed, however, when drawing a picture, we often need to pre-process the image before it can be drawn. For example, it is time-consuming to read the image first. If we use a thread for preprocessing, and a thread for drawing, we can effectively improve the drawing efficiency. I will share with you the code below:
Mainactivity. Java code
Package com. zyb. buffer;
Import java. Lang. Reflect. field;
Import java. util. arraylist;
Import java. util. List;
Import Android. App. activity;
Import Android. Graphics. Bitmap;
Import Android. Graphics. bitmapfactory;
Import Android. Graphics. Canvas;
Import Android. Graphics. paint;
Import Android. Graphics. rect;
Import Android. OS. Bundle;
Import Android. View. surfaceholder;
Import Android. View. surfaceview;
Import Android. View. view;
Import Android. widget. Button;
Public class mainactivity extends activity {
Private surfaceview;
// Used to control surfaceview
Private surfaceholder holder;
// ID of all images in the resource file
Private list <integer> imgids = new arraylist <integer> ();
Private Bitmap bitmap;
// Picture width and height
Private int imgw, imgh;
// Whether the program exits
Private Boolean isexit = false;
@ Override
Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Setcontentview (R. layout. Main );
Surfaceview = (surfaceview) findviewbyid (R. Id. surfaceview );
Holder = surfaceview. getholder ();
Getimgs ();
Button draw = (button) findviewbyid (R. Id. Draw );
Draw. setonclicklistener (New View. onclicklistener (){
@ Override
Public void onclick (view arg0 ){
New thread (New readthread (). Start ();
New thread (New drawthread (). Start ();
}
});
}
/**
* Obtain all images in the resource file.
*/
Public void getimgs (){
Class CLS = R. drawable. Class;
Field [] fields = Cls. getdeclaredfields ();
For (field F: fields ){
// Filter the default icon
If (! F. getname (). Equals ("icon ")){
Try {
// Obtain the image ID
Int id = f. getint (CLS );
Imgids. Add (ID );
} Catch (illegalargumentexception e ){
E. printstacktrace ();
} Catch (illegalaccessexception e ){
E. printstacktrace ();
}
}
}
}
/**
* Image reading thread
* @ Author Administrator
*
*/
Private class readthread implements runnable {
Int Index = 0;
@ Override
Public void run (){
While (! Isexit ){
Bitmap = bitmapfactory. decoderesource (getresources (), imgids. Get (INDEX ));
Imgw = bitmap. getwidth ();
Imgh = bitmap. getheight ();
Index ++;
// Read the last one and read it again
If (Index = imgids. Size ()){
Index = 0;
}
}
}
}
/**
* Drawing thread
* @ Author Administrator
*
*/
Private class drawthread implements runnable {
@ Override
Public void run (){
While (! Isexit ){
If (Bitmap! = NULL ){
// Lock the rectangular area
Canvas canvas = holder. lockcanvas (New rect (0, 0, imgw, imgh ));
If (canvas! = NULL ){
Try {
Canvas. drawbitmap (bitmap, 0, 0, new paint ());
} Catch (exception e ){
E. printstacktrace ();
} Finally {
// Submit for editing
Holder. unlockcanvasandpost (canvas );
}
}
}
}
}
}
@ Override
Protected void ondestroy (){
Isexit = true;
Super. ondestroy ();
}
}
Main. XML content
<? XML version = "1.0" encoding = "UTF-8"?>
<Linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android"
Android: Orientation = "vertical"
Android: layout_width = "fill_parent"
Android: layout_height = "fill_parent"
>
<Button
Android: Id = "@ + ID/draw"
Android: layout_width = "fill_parent"
Android: layout_height = "wrap_content"
Android: text = "start double buffer plotting"
/>
<Surfaceview
Android: Id = "@ + ID/surfaceview"
Android: layout_width = "fill_parent"
Android: layout_height = "fill_parent"
/>
</Linearlayout>
The running result is several images that are quickly drawn in a loop.