Release: | Author: | Source:
Menglongfei | view: 958 | user attention:
This article introduces the use of surfaceview dual buffering. Dual buffering is a multi-threaded application implemented to prevent animation flash. The dual buffering implementation based on surfaceview is very simple. Just open a thread and draw it in it. This article introduces the dual-buffer implementation based on surfaceview, and introduces similar and more efficient implementation methods. The program running in this article is as follows: open a single thread on the left to read and draw, and open two threads on the right to read an image, a special drawing: comparison, the frame speed of the animation on the right is much faster than that on the left, and neither of the left and right use the thread. sleep (). Why open two
This article introduces the use of surfaceview dual buffering. Dual buffering is a multi-threaded application implemented to prevent animation flash. The dual buffering implementation based on surfaceview is very simple. Just open a thread and draw it in it. This article introduces the dual-buffer implementation based on surfaceview, and introduces similar and more efficient implementation methods.
The program running in this article is as follows. On the left side is to open a single thread to read and draw, and on the right side is to open two threads, one for reading images and one for drawing:
In comparison, the frame speed of the animation on the right is much faster than that on the left, and neither of the Left and Right Use thread. Sleep (). Why do we need to open two threads to read one painting at a time, instead of opening two threads to "read and draw while" as they do on the left? Because surfaceview locks the canvas each time it draws, that is to say, the canvas cannot be painted next time in the same area. To improve the efficiency of double buffering, you have to open a thread to draw a picture, start another thread for preprocessing.
Source code of Main. xml:
View plaincopy to clipboardprint?
Android: layout_width = "fill_parent" Android: layout_height = "fill_parent"
Android: Orientation = "vertical">
Android: layout_width = "wrap_content" Android: layout_height = "wrap_content">
Android: layout_height = "wrap_content" Android: text = "single independent thread">
Android: layout_height = "wrap_content" Android: text = "two independent Threads">
Android: layout_width = "fill_parent" Android: layout_height = "fill_parent">
Android: layout_width = "fill_parent" Android: layout_height = "fill_parent"
Android: Orientation = "vertical">
Android: layout_width = "wrap_content" Android: layout_height = "wrap_content">
Android: layout_height = "wrap_content" Android: text = "single independent thread">
Android: layout_height = "wrap_content" Android: text = "two independent Threads">
Android: layout_width = "fill_parent" Android: layout_height = "fill_parent">
Source code of the program in this article:
View plaincopy to clipboardprint?
Package com. testsurfaceview;
Import java. Lang. Reflect. field;
Import java. util. arraylist;
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. util. log;
Import Android. View. surfaceholder;
Import Android. View. surfaceview;
Import Android. View. view;
Import Android. widget. Button;
Public class testsurfaceview extends activity {
/** Called when the activity is first created .*/
Button btnsinglethread, btndoublethread;
Surfaceview SFV;
Surfaceholder SFH;
Arraylist imglist = new arraylist ();
Int imgwidth, imgheight;
Bitmap bitmap; // read from independent threads and draw from independent threads
@ Override
Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Setcontentview (R. layout. Main );
Btnsinglethread = (button) This. findviewbyid (R. Id. button01 );
Btndoublethread = (button) This. findviewbyid (R. Id. button02 );
Btnsinglethread. setonclicklistener (New clickevent ());
Btndoublethread. setonclicklistener (New clickevent ());
SFV = (surfaceview) This. findviewbyid (R. Id. surfaceview01 );
SFH = SFV. getholder ();
SFH. addcallback (New mycallback (); // automatically runs surfacecreated and surfacechanged
}
Class clickevent implements view. onclicklistener {
@ Override
Public void onclick (view v ){
If (V = btnsinglethread ){
New load_drawimage (0, 0). Start (); // open a thread to read and draw
} Else if (V = btndoublethread ){
New LoadImage (). Start (); // open a thread to read
New drawimage (imgwidth + 10, 0). Start (); // open a thread drawing
}
}
}
Class mycallback implements surfaceholder. Callback {
@ Override
Public void surfacechanged (surfaceholder holder, int format, int width,
Int height ){
Log. I ("surface:", "change ");
}
@ Override
Public void surfacecreated (surfaceholder holder ){
Log. I ("surface:", "CREATE ");
// Use the reflection mechanism to obtain the image ID and size in the Resource
Field [] fields = R. drawable. Class. getdeclaredfields ();
For (field: fields ){
If (! "Icon". Equals (field. getname () // image except icon
{
Int Index = 0;
Try {
Index = field. getint (R. drawable. Class );
} Catch (illegalargumentexception e ){
// Todo auto-generated Catch Block
E. printstacktrace ();
} Catch (illegalaccessexception e ){
// Todo auto-generated Catch Block
E. printstacktrace ();
}
// Save the image ID
Imglist. Add (INDEX );
}
}
// Obtain the image size
Bitmap bmimg = bitmapfactory. decoderesource (getresources (),
Imglist. Get (0 ));
Imgwidth = bmimg. getwidth ();
Imgheight = bmimg. getheight ();
}
@ Override
Public void surfacedestroyed (surfaceholder holder ){
Log. I ("surface:", "Destroy ");
}
}
/*
* Threads for reading and displaying images
*/
Class load_drawimage extends thread {
Int X, Y;
Int imgindex = 0;
Public load_drawimage (int x, int y ){
This. x = X;
This. Y = y;
}
Public void run (){
While (true ){
Canvas c = SFH. lockcanvas (New rect (this. X, this. Y, this. x
+ Imgwidth, this. Y + imgheight ));
Bitmap bmimg = bitmapfactory. decoderesource (getresources (),
Imglist. Get (imgindex ));
C. drawbitmap (bmimg, this. X, this. Y, new paint ());
Imgindex ++;
If (imgindex = imglist. Size ())
Imgindex = 0;
SFH. unlockcanvasandpost (c); // update the Screen Content
}
}
};
/*
* Only responsible for drawing threads
*/
Class drawimage extends thread {
Int X, Y;
Public drawimage (int x, int y ){
This. x = X;
This. Y = y;
}
Public void run (){
While (true ){
If (Bitmap! = NULL) {// if the image is valid
Canvas c = SFH. lockcanvas (New rect (this. X, this. Y, this. x
+ Imgwidth, this. Y + imgheight ));
C. drawbitmap (bitmap, this. X, this. Y, new paint ());
SFH. unlockcanvasandpost (c); // update the Screen Content
}
}
}
};
/*
* Only threads responsible for reading Images
*/
Class LoadImage extends thread {
Int imgindex = 0;
Public void run (){
While (true ){
Bitmap = bitmapfactory. decoderesource (getresources (),
Imglist. Get (imgindex ));
Imgindex ++;
If (imgindex = imglist. Size () // re-read if the end is reached
Imgindex = 0;
}
}
};
}
From: http://www.hqew.com/tech/doc/135410.html