问题
I would like to insert a time counter inside a game. If the time is 0, there would be an AlertDialog which tells the user the time is out, and goes back to the previous Activity. Here is the method (it is inside a class which extends a SurfaceView):
public void showTime(){
time--;
Log.i("GameView time", "" + time);
if (time <= 0){
Log.i("gameview time","time out");
gameTimer.setRunning(false);
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this.getContext());
AlertDialog alert = alt_bld.create();
alert.setTitle("Time is out. You lose.");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
main.onBackPressed();
}});
alert.show();
}
}
The GameTimer class is a Thread:
public class GameTimer extends Thread{
private GameView gameView;
private boolean run;
public GameTimer(GameView gameView){
this.gameView = gameView;
}
public void setRunning(boolean value){
this.run = value;
}
public void run(){
Looper.prepare();
while (run){
try {
gameView.showTime();
sleep(1000);
} catch (Exception e){
e.printStackTrace();
}
}
Looper.loop();
}
}
The AlertDialog appears, but the app crashes, with the message: Only the original thread that created a view hierarchy can touch views. But this is the thread which created... Where's the problem?
回答1:
Do this using Handler or Use
this.runOnUiThread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
}
});
The error itself tells the whole story. And if you are not in Activity/ View's Parent class then use some callback Mechnasim. This will help you to resolve your issue. Cheers.
回答2:
Judging by the error you are getting, you are passing your View object into the Thread class constructor from somewhere else and then trying to use it's method to create an AlertDialog. Unfortunately this will not work. You need to use Handler to send back the message(in your case, time = 0) from your thread to your View class , where you have defined the showTime() method. Define the Handler and then override the handleMesage() method to call your showTime() methid.
Below link can help you get started. http://developer.android.com/reference/android/os/Handler.html
来源:https://stackoverflow.com/questions/9109882/looper-prepare-with-alertdialog