LunarLander: Fix race condition causing crash on exit
When exiting the LunarLander sample, it was possible for the canvas to get destroyed before execution was halted. Added additional synchronization to make sure the current run-state is accounted for before performing a canvas update. Also updated deprecated constants in lunar_layout.xml. Bug: 6164549 Change-Id: I9a710f6b128491f1beece84dd39ab00f4937a4c6
This commit is contained in:
@@ -15,17 +15,17 @@
|
||||
-->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<com.example.android.lunarlander.LunarView
|
||||
android:id="@+id/lunar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" >
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:text="@string/lunar_layout_text_text"
|
||||
|
||||
@@ -149,8 +149,8 @@ public class LunarLander extends Activity {
|
||||
*/
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mLunarView.getThread().pause(); // pause game when Activity pauses
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -196,6 +196,8 @@ class LunarView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
/** Indicate whether the surface has been created & is ready to draw */
|
||||
private boolean mRun = false;
|
||||
|
||||
private final Object mRunLock = new Object();
|
||||
|
||||
/** Scratch rect object. */
|
||||
private RectF mScratchRect;
|
||||
|
||||
@@ -356,7 +358,13 @@ class LunarView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
c = mSurfaceHolder.lockCanvas(null);
|
||||
synchronized (mSurfaceHolder) {
|
||||
if (mMode == STATE_RUNNING) updatePhysics();
|
||||
doDraw(c);
|
||||
// Critical section. Do not allow mRun to be set false until
|
||||
// we are sure all canvas draw operations are complete.
|
||||
//
|
||||
// If mRun has been toggled false, inhibit canvas operations.
|
||||
synchronized (mRunLock) {
|
||||
if (mRun) doDraw(c);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// do this in a finally so that if an exception is thrown
|
||||
@@ -427,8 +435,12 @@ class LunarView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
* @param b true to run, false to shut down
|
||||
*/
|
||||
public void setRunning(boolean b) {
|
||||
// Do not allow mRun to be modified while any canvas operations
|
||||
// are potentially in-flight. See doDraw().
|
||||
synchronized (mRunLock) {
|
||||
mRun = b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the game mode. That is, whether we are running, paused, in the
|
||||
|
||||
Reference in New Issue
Block a user