Yesterday, I posted this picture from the Snake game on my G1 phone:

I received this comment from Alex:
Snake with open/close is a memory leak . As a weather has nothing to do with Android just bad app.
Duplicating the Bug
Here is how I duplicate the bug:
- Start playing a game
- Change the phone orientation, i.e. open or close the keyboard drawer
- Push the trackball up to resume the game
Just repeat steps 2-3 a few times until it crashes, it usually takes a few tries. Is this a memory leak, as Alex suggests?
Diagnosing the Bug
- First, install the free Android SDK. Google provides excellent instructions, so I won’t explain it here.
- Configure your G1 phone for USB debugging. From the home screen, go to Menu -> Settings -> Applications -> Development, and select USB debugging.
- Now connect your G1 phone to your computer via the USB cable.
- Run ddms to start the Dalvik Debug Monitor. You’ll find ddms in the tools directory where you installed the Android SDK.
- Make Snake crash and find the stack trace in the Log.

As you can see, this is an ArrayIndexOutOfBoundsException, not a memory leak. Here is the complete stack trace:
java.lang.ArrayIndexOutOfBoundsException
at com.example.android.snake.TileView.setTile(TileView.java:150)
at com.example.android.snake.SnakeView.updateApples(SnakeView.java:434)
at com.example.android.snake.SnakeView.update(SnakeView.java:405)
at com.example.android.snake.SnakeView.setMode(SnakeView.java:336)
at com.example.android.snake.SnakeView.onKeyDown(SnakeView.java:279)
at android.view.KeyEvent.dispatch(KeyEvent.java:718)
at android.view.View.dispatchKeyEvent(View.java:3154)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:734)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:734)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:734)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1589)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1084)
at android.app.Activity.dispatchKeyEvent(Activity.java:1856)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1560)
at android.view.ViewRoot.deliverKeyEvent(ViewRoot.java:1616)
at android.view.ViewRoot.deliverTrackballEvent(ViewRoot.java:1508)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1201)
at android.os.Handler.dispatchMessage(Handler.java:88)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3739)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
at dalvik.system.NativeStart.main(Native Method)
Avoiding Bugs Like This
I find that most Android bugs occur when Activities pause and resume. Changing screen orientation is a great way to crash many applications. That’s because orientation changes trigger lifecycle events. These events will occur at inopportune moments, such as when you receive phone calls or the user hits the Home button.
Applications that do not properly react to onPause(), onResume(), and other such methods will eventually fail.
You can use the UI/Application Exerciser Monkey to stress test your application. In the emulator, you can simulate incoming phone calls, which will pause the current Activity. You should also open and close the keyboard — repeatedly — while your application is performing tasks.
In summary, you need to brutalize your applications. Try really, really hard to break them. Android is a challenging environment because you must carefully manage threads, react to a complex series of lifecycle events, and deal with limited resources.