Game Development Reference
In-Depth Information
if(!holder.getSurface().isValid())
continue;
Canvas canvas = holder.lockCanvas();
canvas.drawRGB(255, 0, 0);
holder.unlockCanvasAndPost(canvas);
}
}
public
void
pause() {
running =
false
;
while
(
true
) {
try
{
renderThread.join();
return;
}
catch
(InterruptedException e) {
// retry
}
}
}
}
}
This doesn't look all that intimidating, does it? Our activity holds a
FastRenderView
instance as
a member. This is a custom
SurfaceView
subclass that will handle all the thread business and
surface locking for us. To the activity, it looks like a plain-old
View
.
In the
onCreate()
method, we enable full-screen mode, create the
FastRenderView
instance, and
set it as the content view of the activity.
We also override the
onResume()
method this time. In this method, we will start our rendering
thread indirectly by calling the
FastRenderView.resume()
method, which does all the magic
internally. This means that the thread will get started when the activity is initially created
(because
onCreate()
is always followed by a call to
onResume()
). It will also get restarted when
the activity is resumed from a paused state.
This, of course, implies that we have to stop the thread somewhere; otherwise, we'd create
a new thread every time
onResume()
was called. That's where
onPause()
comes in. It calls the
FastRenderView.pause()
method, which will completely stop the thread. The method will not
return before the thread is completely stopped.
So let's look at the core class of this example:
FastRenderView
. It's similar to the
RenderView
classes we implemented in the last couple of examples in that it derives from another
View
class.
In this case, we directly derive it from the
SurfaceView
class. It also implements the
Runnable
interface so that we can pass it to the rendering thread in order for it to run the render thread logic.
The
FastRenderView
class has three members. The
renderThread
member is simply a reference
to the
Thread
instance that will be responsible for executing our rendering thread logic.
The
holder
member is a reference to the
SurfaceHolder
instance that we get from the
SurfaceView
superclass from which we derive. Finally, the
running
member is a simple Boolean
flag we will use to signal the rendering thread that it should stop execution. The
volatile
modifier has a special meaning that we'll get to in a minute.
All we do in the constructor is call the superclass constructor and store the reference to the
SurfaceHolder
in the
holder
member.