在异步线程中启动对话框时出现BadTokenException

时间:2013-02-19 08:27:08

标签: android dialog

我有一个进行异步连接的活动,如下所示:

    new Thread(new Runnable() {
        public void run() {
            try{
                //Make Connection
            }catch(Exception e){
                runOnUiThread(new Runnable() { public void run() { 
                     Dialogs.showErrorDialog(MyActivity.this); //I display an error dialog using this context
                } });
            }
        }
    }).start();

想象一下连接速度很慢,我放弃了启动此线程的活动。如果连接最终顺利,一切都很好,但如果连接失败,则在启动对话框时崩溃,因为上下文不再存在。错误是:

android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4068a558 is not valid; is your activity running?

如何避免此错误?我想检测一下我的活动是否还活着

1)显示一个包含此上下文的对话框(如果我仍然在屏幕上)

2)使用ApplicationContext显示Toast(如果我在屏幕外)

EDITED: 对话框代码如下:

static public void showErrorDialog(Context context){
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setIcon(android.R.drawable.ic_dialog_alert);
    builder.setTitle(R.string.error_title);
    builder.setMessage(R.string.error_content);
    builder.setPositiveButton(R.string.button_ok,null);
    builder.show();
}

2 个答案:

答案 0 :(得分:2)

  

如何避免此错误?

我建议你使用它:

runOnUiThread(new Runnable() { 
   public void run() { 
      if (!(((Activity) context).isFinishing())) { // you need to pass Context.
         Dialogs.showErrorDialog(context);      
      }
   } 
});

让我知道它是否有效。

注意:如果不起作用,我建议您使用AsyncTask代替runOnUiThread()

答案 1 :(得分:0)

无法更改线程中的UI;你使用RunOnUiThread,但UiThread仍在线程中。 您可以使用AsyncTask来执行此操作。

class ConnectionTask extends AsyncTask<Void, Void, Boolean> {

    protected Boolean doInBackground(Void... params) {

        //Make Connection
        boolean flag = connecting(); //flag is connect state: success or fail
        return flag;
    }

    protected void onPostExecute(Boolean result) {
        if (!result) {
            Dialogs.showErrorDialog(MyActivity.this); 
        }
    }

}

然后,使用如下:

ConnectionTask task = new ConnectionTask();
task.execute();