Android: исключение BadTokenException, когда я хочу показать progresssDialog во второй раз

#android #progressdialog

#Android #progressdialog

Вопрос:

У меня проблема, которую я не могу решить…

В своей деятельности я создаю экземпляр класса, подобного этому :

MapView mapView = (MapView) findViewById(R.id.mapview);
myMap = new Map(mapView, this);

Конструктор выглядит следующим образом

 public Map(MapView mapView, Context context) {
    this.context = context;
    this.mapView = mapView;
}
  

И что я хочу сделать, это показать ProgressDialog во время процесса этого класса, поэтому в Map я получил

 private void showPath() {
    progressDialog = ProgressDialog.show(context, "Veuillez patienter", "Calcul de l'itinéraire en cours...", true, false);

    Thread thread = new Thread(this);
    thread.start();
}
  

Когда поток завершен, я делаю

progressDialog.dismiss();

Это работает! Но только один раз… Если я нажму на кнопку «Назад» и повторно открою свою активность, я получу исключение BadTokenException

05-06 23:27:15.941: ERROR/AndroidRuntime(1247): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@44ecc8e8 is not valid; is your activity running?

Я перепробовал все найденные решения, но ни одно не работает… Даже используйте класс, который расширяет AsyncTask.

Спасибо за вашу помощь

Ответ №1:

Как указано в сообщении об ошибке, это потому, что вы пытаетесь показать диалоговое окно в Activity, но Activity не выполняется (уже завершено?). Поэтому, прежде чем показывать диалоговое окно, вы можете убедиться, что действие не завершено:

 public class MyActivity extends Activity {

    public void showDialog(Dialog dialog) {
        if (!isFinishing()) {
            // If activity is not finished, then show this dialog.
            dialog.show();
        }
    }

}
  

Комментарии:

1. Хорошо, я понимаю, но как я могу это сделать? Инструкция dialog.show(); находится в моем классе, который не является Activity…

2. О, это работает! Но я не знаю, действительно ли то, как я это сделал, хорошо… Я создал частный атрибут в своем классе, который является Activity. Я устанавливаю его в конструкторе, и в моем методе я делаю то, что вы мне сказали: if (!isFinishing()) { // If activity is not finished, then show this dialog. dialog.show(); } это хорошо или нет?

3. Если объект вашего класса, который хранит ссылку на Activity, не является долгоживущим объектом, тогда это нормально делать. Прочитайте эту статью об избежании утечек памяти в документе Android для получения дополнительных объяснений.