I want to pop up a dialog box when the user completes the game to show his points and time.
I read about the runOnUiThread
and I tried to implement the solution in my code, but is not working. I get the following error:
"Can't create handler inside thread that has not called Looper.prepare()"
.
I have a bool variable called gameCompleted
in my SurfaceView
class, when this becomes true I call the method showDialogGameCompleted()
which is implemented in the Activity
class. Where am I wrong?
My activity class:
public class Canvastutorial extends Activity {
final Context context = this;
Dialog dialog;
/** Called when the activity is first created. */
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_layout);
}
// THE METHOD I CALL FROM MY SURFACEVIEW CLASS IN ORDER TO SHOW THE DIALOG
public void showDialogGameCompleted()
{
dialog= new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("PUZZLE COMPLETED!");
// set the custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Congratulations!\nPoints: \nMoves: \nTime: ");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.cup);
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
Canvastutorial.this.runOnUiThread(new Runnable() {
public void run() {
dialog.show();
}
});
}
My SurfaceView class:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private CanvasThread canvasthread;
private Canvastutorial canvastutorial= new Canvastutorial();
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
canvasthread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
canvasthread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
@Override
public void onDraw(Canvas canvas) {
if(canvas!=null)
{
switch (w)
{
case MENU:
//menu stuff
break;
case GAME:
// WHEN THE GAME IS COMPLETED I CALL THE
//showDialogGameCompleted METHOD WHICH IS IMPLEMENTED IN MY ACTIVITY CLASS
if(gameCompleted)
{
gameCompleted=false;
canvastutorial.showDialogGameCompleted();
}
break;
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
canvasthread.setRunning(true);
canvasthread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
canvasthread.setRunning(false);
while (retry) {
try {
canvasthread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
My Thread class:
public class CanvasThread extends Thread {
private SurfaceHolder _surfaceHolder;
private MySurfaceView _mySurfaceView;
private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder, MySurfaceView mySurfaceView) {
_surfaceHolder = surfaceHolder;
_mySurfaceView = mySurfaceView;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run)
{
c = null;
try
{
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder)
{
_mySurfaceView.onDraw(c);
}
}
finally
{
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null)
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}