The previous article briefly introduced the basic use of Surfaceview, this time on the introduction of Surfaceview and multithreading mix. Surfaceview is a multi-threaded application that is designed to prevent animation from flashing. The multithreading usage of Android is exactly the same as that of Java, this article does not introduce multithreading. Directly to explain the mixed use of Surfaceview and multithreading, that is, open a thread to read the picture, the other thread is specialized in drawing.
This program runs the screenshot below, the left is open a single thread reading and drawing, the right side is open two threads, a special read pictures, a special drawing:
Contrast, the right animation frame speed is significantly faster than the left side, neither of the use of Thread.Sleep (). Why do you have to open two threads one to read a picture instead of opening two threads like the left side of the "read while painting"? Because Surfaceview every time the drawing will be locked canvas, that is, the same area did not finish painting the next time can not be painted, so to improve the efficiency of animation playback, you have to open a thread specialized drawing, open another thread to do preprocessing work.
Main.xml's source code:
<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width= "Fill_ Parent "android:layout_height=" fill_parent "
android:orientation=" vertical ">
<linearlayout android: Id= "@+id/linearlayout01"
android:layout_width= "wrap_content" android:layout_height= "wrap_content" >
<button android:id= "@+id/button01" android:layout_width= wrap_content "android:layout_height=" Wrap_
Content "android:text=" single Independent thread >
<button android:id= "@+id/button02" android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content" android:text= "two Independent threads" >
<surfaceview android:id= "@+id/" SurfaceView01 "
android:layout_width=" fill_parent "android:layout_height=" Fill_parent ">
The source code of this program:
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; The public class Testsurfaceview extends activity {/** called the ' when the ' is the ' The activity ' is the ' the '
Thread, Btndoublethread;
Surfaceview SFV;
Surfaceholder SFH;
ArrayList imglist = new ArrayList ();
int ImgWidth, imgheight; Bitmap bitmap;//Independent thread reads, independent thread drawing @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 ())//Auto Run surfacecreated and surfacechanged} class Clickevent implements View.onclic
Klistener {@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 Loadi
Mage (). Start ();//Open a thread to read the new DrawImage (imgwidth + 0). Start ();//Open a thread drawing}}} Class Mycallback implements Surfaceholder.callback {@Override public void surfacechanged (Surfaceho
Lder holder, int format, int width, int height) {log.i ("Surface:", "change"); @Override public void surfacecreated (Surfaceholder holder) {log.i ("Surface:", "Create");
Use reflection mechanism to get picture IDs and dimensions in resources field[] fields = R.drawable.class.getdeclaredfields (); for (Field field:fields) {if (!)
Icon ". Equals (Field.getname ()))//except icon image {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 Picture ID Imglist.add (index); }///Get 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")
;
}/* * Read and display the picture's thread/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).
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 screen display content}};
* * * Only responsible for drawing thread/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 screen display content}}};
* * * Only responsible for reading the picture of the thread/class LoadImage extends thread {int imgindex = 0;
public void Run () {while (true) {bitmap = Bitmapfactory.decoderesource (Getresources ()),
Imglist.get (Imgindex));
imgindex++; if (Imgindex = = Imglist.size ())//If to the end then re-read imgindex = 0;
}
}
};
}
The above is the entire contents of this article, I hope to learn more about Android software programming help.