Flickering While Using Surface View
Solution 1:
If you call lockCanvas()
, you need to draw on every pixel in the dirty rect. Since you're calling it without a dirty rect, that means updating every pixel on the Canvas.
I believe the problem with your code is that, when mTouched
is false
, you're not drawing anything at all. Because the Surface is double- or triple-buffered, you're re-displaying the contents of a previous frame, which is going to cause a vibration effect.
I think all you need to do is move the test for mTouched
before the lockCanvas()
call, so you don't flip the buffers if you're not going to draw anything.
You may want to look through the SurfaceView lifecycle appendix in the graphics architecture doc if you haven't seen it before, as the thread management sometimes yields surprises.
Solution 2:
Clear your surfaceviewholder with these lines and make it ready again before playing or drawing any thing on it.
These lines will clear the surface view after using surfaceview at least once
Canvascanvas= mSurfaceHolder.lockCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// Draw someting
mSurfaceHolder.unlockCanvasAndPost(canvas);
mSurfaceHolder.setFormat(PixelFormat.TRANSPARENT);
mSurfaceHolder.setFormat(PixelFormat.OPAQUE);
Here this line will make it ready for second time playing the video
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
Solution 3:
flickering is usually a weird issue, so that's my best guess on how to solve on your specific case.
I can see from your code, you're declaring a series of different commands to be applied to the canvas, those are being drawn one at a time in the canvas, in the order of the code, at the moment that your code lockCanvas
and the combination of those elements that I believe is the reason for your flickering.
Because:
- those draws are not being performed during the system VSYNC (because SurfaceViews)
- it's done one at a time in sequence (which takes time and makes the flicker noticeable).
I can think of two solutions for this:
I can see you're only calling
drawColor
anddrawRect
on your view. Also, you're not performing any time consuming on it. So I really don't see a reason for the usage ofSurfaceView
. Refactor the class to a normalextends View
and perform them drawing insideonDraw
and callinvalidate()
whenever necessary to re-draw (I believe it will be inside the touch events)If there's some code you omit for brevity that actually does make the
SurfaceView
really necessary, you can allocate a temporary canvas with a bitmap using the same size of the screen canvas. Do all the drawing on this temporary canvas and use only thedrawBitmap
call on your on-screen canvas. A small sample code for this follows.
.
// init your objects inside the `surfaceCreated` callbackBitmaptempBitmap= Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
CanvastempCanvas=newCanvas(tempBitmap);
// then on your thread.while(mRunning){
tempCanvas. // ... do all your drawing operations hereCanvascanvas= mSurfaceHolder.lockCanvas();
canvas.drawBitmap(tempBitmap, 0, 0, null);
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
remember that's just a sample code and not a complete solution, you'll have to do all the normal checks for canvas is valid, etc.
Post a Comment for "Flickering While Using Surface View"