1. I heard that the game development are used Surfaceview, the internet search, said is Surfaceview in the update view, the use of double caching mechanism, can improve the efficiency of the update, enhance the user experience. The following two paragraphs pasted from other people's blog, said is quite clear.
Note:on each pass you retrieve the canvas from the Surfaceholder, the previous state of the canvas would be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, your can clear the previous state of the Canvas by filling in a color with drawcolor () or setting a background Image with Drawbitmap (). Otherwise, you'll see traces of the drawings you previously performed.
It can be understood as: Surfaceview uses two canvases, one frontcanvas and one backcanvas to update the view, and each time it actually shows that the Frontcanvas,backcanvas is storing the view before the last change. When using Lockcanvas () to get the canvas, you get the actual backcanvas instead of the Frontcanvas being displayed, and then you draw a new view on the Backcanvas that you get. Again Unlockcanvasandpost (canvas) This view, then upload this canvas will replace the original Frontcanvas as the new Frontcanvas, the original Frontcanvas will switch to the background as Backcanvas. For example, if you have already drawn views A and B two times, then you call Lockcanvas () to get the view, get a instead of the B that is being displayed, and then you say redraw the C view to upload, then C will replace B as the new Frontcanvas display on the Surfaceview , the original B is converted to Backcanvas.
2. On the net leaf out wrote short code, the result send to background time will crash. Debug found that the reason is not checked surfaceholder get the canvas is not empty. After surfacedestroyed, the canvas must be gone, so check it out.
Public classDemosurfaceviewextendsSurfaceviewImplementscallback{loopthread thread; PublicDemosurfaceview (Context context) {Super(context); Init (); } Private voidinit () {Surfaceholder holder=Getholder (); Thread=Newloopthread (Holder, GetContext ()); Holder.addcallback ( This); } @Override Public voidSurfacechanged (Surfaceholder holder,intFormatintwidth,intheight) {} @Override Public voidsurfacecreated (Surfaceholder holder) {thread.isrunning=true; Thread.Start (); } @Override Public voidsurfacedestroyed (Surfaceholder holder) {LOG.I ("Hailin", "surfacedestroyed"); Thread.isrunning=false; Try{thread.join (); } Catch(interruptedexception e) {e.printstacktrace (); } } classLoopthreadextendsthread{Surfaceholder Surfaceholder; Context context; Booleanisrunning; floatRadius =10f; Paint paint; Publicloopthread (Surfaceholder surfaceholder,context Context) { This. Surfaceholder =Surfaceholder; This. Context =context; IsRunning=false; Paint=NewPaint (); Paint.setcolor (Color.yellow); Paint.setstyle (Paint.Style.STROKE); } @Override Public voidrun () {Canvas C=NULL; while(isrunning) {Try{ synchronized(surfaceholder) {if(Surfaceholder = =NULL) {log.i ("Hailin", "surfaceholder = = NULL"); } C= Surfaceholder.lockcanvas (NULL); if(c = =NULL) {log.i ("Hailin", "c = = null"); return; } dodraw (c); Thread.Sleep (50); Surfaceholder.unlockcanvasandpost (c); } } Catch(interruptedexception e) {e.printstacktrace (); } finally { } } } Public voidDodraw (Canvas c) {c.drawcolor (color.black); C.translate (200, 200); C.drawcircle (0,0, radius++, paint); if(Radius > 100) {radius=10f; } } } }
View Code
3. Follow the "Crazy Android Handout" to break the code, found that after tapping the screen in the surfacecreated inside the background image is always lost. If you set the background directly with Surfaceview.setbackground, clicking on the screen picture will be obscured by the non-black part of the background map (the background image would have been a white background, but the picture would have turned black). Finally, you can only re-draw the background map in the Ontouch.
Public classSvtestextendsActivity {PrivateSurfaceholder Holder; PrivatePaint paint; PrivateSurfaceview surface; PrivateCanvas Canvas; Private Booleanistouched; PrivateBitmap Mbitmap; @Override Public voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); This. Setcontentview (R.layout.svtest); Paint=NewPaint (); Surface= (Surfaceview) This. Findviewbyid (R.id.svtest); FinalBitmap back = Bitmapfactory.decoderesource (svtest. This. Getresources (), r.drawable.ic_launcher); Displaymetrics DM=getresources (). Getdisplaymetrics (); intMscreenwidth =Dm.widthpixels; intMscreenheight =Dm.heightpixels; Mbitmap= Bitmap.createscaledbitmap (back, Mscreenwidth, Mscreenheight,true); //actually it set a drawable with pure color as background//Surface.setbackgroundcolor (Color.White); //Set Background drawable//Surface.setbackgroundresource (r.drawable.ic_launcher);Holder=Surface.getholder (); Holder.addcallback (NewCallback () {@Override Public voidsurfacecreated (Surfaceholder holder) {//TODO auto-generated Method StubLOG.I ("Hailin", "surfacecreated"); //Set BackgroundCanvas =Holder.lockcanvas (); Canvas.drawbitmap (Mbitmap,0, 0,NULL); Holder.unlockcanvasandpost (canvas); } @Override Public voidSurfacechanged (Surfaceholder holder,intformat,intWidthintheight) { //TODO auto-generated Method StubLOG.I ("Hailin", "surfacechanged"); } @Override Public voidsurfacedestroyed (Surfaceholder holder) {//TODO auto-generated Method StubLOG.I ("Hailin", "surfacedestroyed"); } }); Surface.setontouchlistener (NewOntouchlistener () {@Override Public BooleanOnTouch (View V, motionevent event) {//TODO auto-generated Method Stub if(event.getaction () = =Motionevent.action_down) { if(!istouched) { //Set Background againCanvas =Holder.lockcanvas (); Canvas.drawbitmap (Mbitmap,0, 0,NULL); Holder.unlockcanvasandpost (canvas); Istouched=true; } intCX = (int) Event.getx (); intcy = (int) event.gety (); Canvas Canvas= Holder.lockcanvas (NewRect (cx-50, CY-50, CX +, CY + 50)); Canvas.save (); Canvas.rotate (30, CX, CY); Paint.setcolor (color.red); Canvas.drawrect (CX-CY-50, CX, CY, paint); Canvas.restore (); Paint.setcolor (Color.green); Canvas.drawrect (CX, CY, CX+ 50, CY +, paint); Holder.unlockcanvasandpost (canvas); } return false; } }); } @Override Public voidOnresume () {Super. Onresume (); LOG.I ("Hailin", "Onresume"); } @Override Public voidOnPause () {Super. OnPause (); LOG.I ("Hailin", "OnPause"); } @Override Public voidOnDestroy () {Super. OnDestroy (); LOG.I ("Hailin", "OnDestroy"); } }
View Code
Problems encountered in Surfaceview learning