Game Development Reference
In-Depth Information
behind all rendering on Android, and it is ultimately responsible for pushing all pixels to the GPU.
The Surface can be hardware accelerated in some cases. We don't care much about that fact,
though. All we need to know is that it is a more direct way to render things to the screen.
Our goal is it to perform our rendering in a separate thread so that we do not hog the UI thread,
which is busy with other things. The SurfaceView class provides us with a way to render to it
from a thread other than the UI thread.
SurfaceHolder and Locking
In order to render to a SurfaceView from a different thread than the UI thread, we need to acquire
an instance of the SurfaceHolder class, like this:
SurfaceHolder holder = surfaceView.getHolder();
The SurfaceHolder is a wrapper around the Surface , and does some bookkeeping for us.
It provides us with two methods:
Canvas SurfaceHolder.lockCanvas();
SurfaceHolder.unlockAndPost(Canvas canvas);
The first method locks the Surface for rendering and returns a nice Canvas instance we can use.
The second method unlocks the Surface again and makes sure that what we've drawn via the
Canvas gets displayed on the screen. We will use these two methods in our rendering thread to
acquire the Canvas , render with it, and finally make the image we just rendered visible on the
screen. The Canvas we have to pass to the SurfaceHolder.unlockAndPost() method must be the
one we received from the SurfaceHolder.lockCanvas() method.
The Surface is not immediately created when the SurfaceView is instantiated. Instead, it is
created asynchronously. The surface will be destroyed each time the activity is paused, and it
will be re-created when the activity is resumed.
Surface Creation and Validity
We cannot acquire the Canvas from the SurfaceHolder as long as the Surface is not yet valid.
However, we can check whether the Surface has been created or not via the
following statement:
boolean isCreated = surfaceHolder.getSurface().isValid();
If this method returns true , we can safely lock the surface and draw to it via the Canvas we
receive. We have to make absolutely sure that we unlock the Surface again after a call to
SurfaceHolder.lockCanvas() , or else our activity might lock up the phone!
Putting It All Together
So how do we integrate all of this with a separate rendering thread as well as with the activity
life cycle? The best way to figure this out is to look at some actual code. Listing 4-16 shows a
complete example that performs the rendering in a separate thread on a SurfaceView .
 
Search WWH ::




Custom Search