2

我在doInBackground 方法progressdialog中使用AsyncTask打开一个问题正在从数据库加载,问题成功加载后,进度对话框将关闭

但我的问题是有一段时间我收到以下错误

      android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRoot$W@44757528 is not valid; is your activity running?

通过进行一些谷歌搜索,我发现我可能正在保留对已被破坏的上下文的引用(明确地,或通过创建对话框或吐司或其他一些依赖项)(通常是因为您正在使用 onCreateDialog或者您将 Activity 传递给在 Activity 被销毁时没有被销毁的其他进程)。

因此,如果活动在对话框被关闭之前被破坏,我在下面放置了关闭progressdialog的代码

    protected void onDestroy() {
      if (pdForNewQuestion != null)
            pdForNewQuestion.dismiss();
      super.onDestroy();

    }

但我仍然面临这个问题。我没有破坏任何活动,但有时会突然出现错误,有时会正常工作

异步代码如下

      // Start new question in every 60 seconds  :)
    new Thread(new Runnable() {
        public void run() {
            while (true) {

                    try {
                        Thread.sleep(1000);
                        mProgressStatus++;

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    runOnUiThread(new Runnable() {
                        public void run() {
                            mProgress.setProgress(mProgressStatus);
                            txtCountingNum.setText((timer--) + "\nSec.");
                            if (timer < 0) {
                                questionLoadWithAsyncTask();
                            }
                        }
                    });

            }

        }
    }).start();




       public void questionLoadWithAsyncTask() {

    new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            pdForNewQuestion = new ProgressDialog(QuizActivity.this);
            pdForNewQuestion.setTitle("Please wait...");
            pdForNewQuestion.setMessage("Question is loading...");
            pdForNewQuestion.setCancelable(false);
            pdForNewQuestion.setIndeterminate(true);
            pdForNewQuestion.show();
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            wordsCursor = dbHelper.getRandomWords();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            if (pdForNewQuestion != null) {
                pdForNewQuestion.dismiss();
            }
        }

    }.execute();

}
4

4 回答 4

1

检查对话框是否正在显示,如果对话框正在显示,那么只能像这样关闭..

@Override
protected void onDestroy() {
    if (pdForNewQuestion != null) {
        if (pdForNewQuestion.isShowing()) {
            pdForNewQuestion.dismiss();
            pdForNewQuestion = null;
        }
    }
    super.onDestroy();
}
于 2013-10-17T05:32:35.227 回答
0

您正在新线程内运行无限循环,但没有中断循环并停止该线程。即使活动进入后台,它也会在后台无限运行。工作完成后尝试停止线程。

于 2013-10-17T06:45:49.357 回答
0

首先,你为什么要开始你的AsyncTask内心Thread?据我了解,您正试图AsyncTask每 60 秒开始一次并填写一个新问题。有一个更好的方法来做到这一点,只使用 aHandlerAsyncTask

创建一个每秒钟运行的Handler帖子Runnable,并根据结果启动您的AsyncTask

    int mSeconds = 0;

    Handler mHandler = new Handler();
    mHandler.postDelayed(new Runnable() {

        @Override
        public void run() {

            if(mSeconds == 60){
                new QuestionLoader().execute();
                mSeconds = 0;
            }
            mHandler.postDelayed(this, 1000);
            mSeconds++;

        }
    }, 1000);

你可以AsyncTask像这样创建你的:

    private class QuestionLoader extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        pdForNewQuestion = new ProgressDialog(MainActivity.this);
        pdForNewQuestion.setTitle("Please wait...");
        pdForNewQuestion.setMessage("Question is loading...");
        pdForNewQuestion.setCancelable(false);
        pdForNewQuestion.setIndeterminate(true);
        pdForNewQuestion.show();

    }

    @Override
    protected Void doInBackground(Void... params) {
          wordsCursor = dbHelper.getRandomWords();
        return null;
    }

    @Override
    protected void onPostExecute(Void result){
        super.onPostExecute(result);
        if(pdForNewQuestion != null && pdForNewQuestion.isShowing()){
            pdForNewQuestion.dismiss();
        }
    }

}
于 2013-10-17T06:58:06.120 回答
0

这通常是由于您的应用程序尝试使用以前完成的 Activity 作为上下文来显示对话框。然后在显示对话框之前检查活动是否没有被其他一些应用程序或其他触发器关闭

if (!isFinishing()) {
    //showdialog here
    }
于 2019-01-18T10:12:09.097 回答