Game Development Reference
In-Depth Information
Main thread: getKeyEvents() ->
keyEvents={KeyEvent2}, keyEventsBuffer={ }, pool={KeyEvent1}
UI thread: onKey() ->
keyEvents={KeyEvent2}, keyEventsBuffer={KeyEvent1}, pool={ }
1.
We get a new event in the UI thread. There's nothing in the
Pool
yet, so
a new
KeyEvent
instance (
KeyEvent1
) is created and inserted into the
keyEventsBuffer
list.
2.
We call
getKeyEvents()
on the main thread.
getKeyEvents()
takes
KeyEvent1
from the
keyEventsBuffer
list and puts it into the
keyEvents
list that is returns to the caller.
3.
We get another event on the UI thread. We still have nothing in the
Pool
,
so a new
KeyEvent
instance (
KeyEvent2
) is created and inserted into the
keyEventsBuffer
list.
4.
The main thread calls
getKeyEvents()
again. Now, something
interesting happens. Upon entry into the method, the
keyEvents
list
still holds
KeyEvent1
. The insertion loop will place that event into our
Pool
. It then clears the
keyEvents
list and inserts any
KeyEvent
into the
keyEventsBuffer
, in this case,
KeyEvent2
. We just recycled a key event.
5.
Another key event arrives on the UI thread. This time, we have a free
KeyEvent
in our
Pool
, which we happily reuse. Incredibly, there's no
garbage collection!
This mechanism comes with one caveat, which is that we have to call
KeyboardHandler.getKeyEvents()
frequently or the
keyEvents
list fills up quickly, and no objects
are returned to the
Pool
. Problems can be avoided as long as we remember this.
Touch Handlers
Now it is time to consider fragmentation. In Chapter 4, we revealed that multitouch is only
supported on Android versions greater than 1.6. All the nice constants we used in our multitouch
code (for example,
MotionEvent.ACTION_POINTER_ID_MASK
) are not available to us on Android
1.5 or 1.6. We can use them in our code if we set the build target of our project to an Android
version that has this API; however, the application will crash on any device running Android 1.5
or 1.6. We want our games to run on all currently available Android versions, so how do we solve
this problem?
We employ a simple trick. We write two handlers, one using the single-touch API in Android 1.5,
and another using the multitouch API in Android 2.0 and above. This is safe as long as we don't
execute the multitouch handler code on an Android device lower than version 2.0. The VM won't
load the code, and it won't throw exceptions continuously. All we need to do is find out which
Android version the device is running and instantiate the proper handler. You'll see how this
works when we discuss the
AndroidInput
class. For now, let's concentrate on the two handlers.