Thursday, June 3, 2010

IllegalThreadStateException in LunarLander, a sample Android code from Google

I think it can be classified as a bug in Lunar Lander game, in the SDK samples folder: /samples/LunarLander/:

Start the game and exit by pressing HOME key when the space ship is falling downing, then re-enter the game, it will be a IllegalThreadStateException thrown! and the App will be terminated.



My previous exercise("Android SurfaceView", "SurfaceView in a FrameLaout inside another LinearLayout" and "SurfaceView overlap with a LinearLayout") was implemented by reference to the sample code. Such that all of them inherit the bug.

My solution is to move the code "thread = new MySurfaceThread(getHolder(), this);" from constructor of the SurfaceView to inside the surfaceCreated() method.



From the video, it can be noted that if the App exit by HOME key, then re-enter, the onCreate() method of the Activity, and also the constructor of the SurfaceView will not be called, the App continuous from the previous state; so no object of the Thread will be instanced. That's why the IllegalThreadStateException thrown in the original approach.

But...if the App exit by BACK key, then re-enter, the onCreate() method of the Activity, and the constructor of the SurfaceView will be called, and will not have this problem.

The modified version of AndroidMergeSurfaceView can be downloaded here.





3 comments:

unanimouse said...

Thanks for the simple fix! All of the other solutions seemed much more difficult and wrong.

Steve said...

Hello,

I know this is an old post, but what exactly triggers the thread to run or te canvas the surface view to invalidate.

I am trying something similar in my own app. but nothing get drawn, furthermore, I tried throwing an exception in the surfacecreated event but it's not getting fired.

Erik said...

hello unanimouse, Thx.

hello Steve,

when the app run, the SurfaceView displayed, surfaceCreated() of MySurfaceView will be called, and then call thread.start() to start the thread.

myThreadSurfaceView.onDraw() inside run() of MySurfaceThread re-draw the canvas.