Android: Using postInvalidate() to trigger onDraw() with SurfaceView

When trying a different approach to controlling the onDraw() timing in my app, I stumbled upon a little roadblock which was not mentioned in the documentation.

I tried to use postInvalidateDelayed() to control the amount of time it took for the next redraw to happen, but for some reason it seemed to be ignored. I've even tried all invalidate(), postInvalidate() and postInvalidateDelayed() with threading.

invalidate() had to be called in the UI thread, however postInvalidate() and postInvalidateDelayed() could be called from any thread.

The reason is the SurfaceView class calls the setWillNotDraw() method to prevent the normal drawing methods of the View class.

That method has to be called in the UI thread, however it cannot be called in the constructor as the Surface has not yet been created.

You should call setWillNotDraw(false) during the surfaceCreated() stage of initialisation. Doing that, you sacrifice a bit of performance that the SurfaceView offers.

If you'd rather wait for a specific time to disable the SurfaceView custom drawing, use an AsyncTask.

new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
return null;
}

@Override
protected void onPostExecute(Void result) {
// This allows View.postInvalidate() to work with a SurfaceView
setWillNotDraw(false);
// This is not needed as setWillNotDraw() forces a redraw.
// m_drawScoreboard.postInvalidateEnabled = true;
}
}.execute();

That said, I still found it was better (performance-wise) to rewrite my code so it supported timed drawings in the drawing thread without changing "will not draw".

[ SurfaceView ignoring postInvalidate()? and Extended SurfaceView's onDraw() method never called ]

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog