Подтвердить что ты не робот

Android - увольнениеDialog не отменяет диалог

Я использую showDialog() и dismissDialog(), чтобы показывать диалоги прогресса в моем приложении. Перемещено от создания диалога и вызова show() на нем, чтобы использовать это, чтобы сохранить состояние при изменении ориентации.

Но когда я меняю ориентацию с портретом → пейзаж → портрет, dismissDialog() больше не отклоняет диалог. Диалог остается там все время, и мне нужно нажать кнопку "Назад", чтобы он исчез.

Любая причина, по которой она будет вести себя таким образом?

Edit

Чтобы решить эту проблему, я попытался добавить removeDialog() в onDestroy(), чтобы диалоговое окно не создавалось/отображалось дважды и до изменения ориентации, диалог удаляется. Пробовал добавлять записи журнала и видеть, что происходит

05-21 12:35:14.064: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:14.064: DEBUG/MyClass(193): *************onCreareDialog

05-21 12:35:15.385: DEBUG/MyClass(193): *************onSaveInstanceState
05-21 12:35:15.415: DEBUG/MyClass(193): *************onDestroy

05-21 12:35:15.585: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:15.585: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:15.715: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:17.214: DEBUG/MyClass(193): *************onSaveInstanceState
05-21 12:35:17.214: DEBUG/MyClass(193): *************onDestroy

05-21 12:35:17.275: ERROR/WindowManager(193): android.view.WindowLeaked: Activity com.android.MyClass has leaked window [email protected] that was originally added here

05-21 12:35:17.395: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:17.395: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:17.475: DEBUG/MyClass(193): *************onCreareDialog

Если мы увидим здесь, сначала, когда отображается действие, onCreateDialog вызывается один раз и при изменении ориентации вызывается onSaveInstanceState и onDestroy.

Но после этого onCreateDialog вызывается дважды (один раз вызовом showDialog, который я делаю, но почему второй раз?), и это происходит каждый раз, когда я меняю ориентацию и далее.

Любая идея, почему это происходит?

Еще раз спасибо

4b9b3361

Ответ 1

Лучшее решение для меня, похоже, использует removeDialog (id) вместо rejectDialog(); Меньше повторного использования таким образом, но безопаснее (ничего не бросает) и никаких проблем при изменении ориентации.

Ответ 2

Я столкнулся с этим при показе диалога в переопределении onCreate Activity. Попробуйте переместить код, который заставляет диалоговое окно отображаться в переопределении onPostCreate. Кажется, это работает для меня.

Ответ 3

Я потратил больше дня на такую ​​проблему, когда диалоги не увольнялись при вызове функции dispDialog. Это произошло после моего первого поворота экрана и никогда не работало после этого. Я использовал внешнюю AsyncTask, которая была явно указана в ядре.

В итоге решение было действительно простым. removeDialog(int) вместо dismissDialog(int).

Я потратил то, что чувствовал себя навсегда, доказывая, что я делаю увольнение на правильной деятельности и проверяю количество раз, когда что-то называлось и т.д., но это было вызвано некоторыми из jiggerypokery за кулисами.

Ответ 4

Недавно я столкнулся с этой проблемой. У меня есть приложение со многими действиями, все из которых требуют доступа к глобальным объектам (соединения db, списки данных и т.д.), И поэтому я переопределял класс Application. С этой целью я понял, что все, что мне нужно, это ссылка на последний экземпляр диалогового окна прогресса в моем runnable, который я использовал, чтобы отклонить диалог. Это то, что я придумал, и он изящно переживает переориентацию телефона:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);

    mHandler = new Handler();
    mApplication = (MyApplication)getApplication();

    mFileStorage = (CheckBoxPreference)getPreferenceScreen().findPreference("fileStorage");

    mProgressDialog = new ProgressDialog(this);

    mProgressDialog.setTitle("Location Update");
    mProgressDialog.setMessage("Moving databases to new storage location.");
    mProgressDialog.setIndeterminate(true);
    mProgressDialog.setCancelable(false);
    mProgressDialog.setCanceledOnTouchOutside(false);

    mApplication.setProgressDialog(mProgressDialog);
}

@Override
protected void onResume() {
    super.onResume();

    mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    mPreferences.registerOnSharedPreferenceChangeListener(this);

    if (sUpdateThread != null && sUpdateThread.isAlive()) {
        mProgressDialog.show();
    }
}

@Override
protected void onPause() {
    super.onPause();

    mPreferences.unregisterOnSharedPreferenceChangeListener(this);

    if (sUpdateThread != null && sUpdateThread.isAlive()) {
        mProgressDialog.hide();
        mApplication.setProgressDialog(null);
    }
}

.... случайный материал здесь....

private Runnable showProgressRunnable = new Runnable() {
    public void run() {
        mProgressDialog.show();
    }
};

private Runnable hideProgressRunnable = new Runnable() {
    public void run() {
        if (mApplication.getProgressDialog() != null) {
            mApplication.getProgressDialog().dismiss();
        }
    }
};

В моем потоке запускается mHandler.post(showProgressRunnable) при запуске задачи, а затем после завершения задачи выполняется mHandler.post(hideProgressRunnable). Поскольку ссылка на последний ProgressDialog теперь хранится в классе Application, я могу надежно закрыть ее, так как я больше не держусь за старую ссылку на объект.

Ссылка для потомков: http://developer.android.com/reference/android/app/Application.html

Ответ 5

После нажатия кнопки "домой" и перехода на приложение morelocal (сменить язык устройства), когда я вернусь в свое приложение, новые диалоговые окна не могут быть закрыты с помощью функции dispDialog (я запустил диалог из действия onCreate).

Решение заключалось в вызове removeDialog вместо dismissDialog(). Это было рекомендовано Харри выше, многие спасибо.

Я создал отчет об ошибке Android:

13858


Решение состоит в том, чтобы создать диалог, используя OnPostCreate вместо OnCreate. Я добавил эту информацию в отчет об ошибке и рекомендовал улучшить диалоговую документацию .

Ответ 6

Помните, что каждый раз, когда вы меняете ориентацию, создается новый экземпляр вашего Activity (и, следовательно, вашего Dialog через onCreateDialog). Вы можете проверить это, добавив оператор журнала в любой конструктор.

Хотя трудно сказать, не взглянув на свой код, я предполагаю, что вы вызываете dismissDialog в более старом экземпляре вашего Activity.

Рассмотрим следующий Activity, который просто показывает пустой Dialog при нажатии кнопки и запускает TimerTask, чтобы отклонить его через 10 секунд:

public class Test extends Activity {

    private Dialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);     
        setContentView(R.layout.test);
        Button btn = (Button) findViewById(R.id.testButton);
        btn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                new Timer().schedule(new TimerTask() {
                    @Override public void run() { dialog.dismiss(); }
                }, 10000);
                Test.this.showDialog(1);
            }
        });
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        if(id == 1) {
            if(dialog == null) { dialog = new Dialog(this); }
            return dialog;
        }
        return super.onCreateDialog(id);
    }
}

Этот код имеет проблему, подобную той, которую вы описываете: если - в течение 10 секунд - ориентация изменилась, Dialog никогда не увольняется. Зачем? Поскольку во время TimerTask был run, был создан целый набор экземпляров Test и Dialog (во время изменения ориентации), а переменная экземпляра TimerTask Dialog ссылается на экземпляр Test который отличается от того, который в данный момент активен на экране.

Очевидно, есть несколько способов решить эту проблему (в основном в зависимости от вашего приложения), один быстрый (грязный?) способ исправить вышеуказанный код состоит в том, чтобы просто сделать поле Dialog static:

private static Dialog dialog;

Ответ 7

После поиска по всем форумам я просто сделал следующее:

Я вызываю showDialog (MyDialogID) и отклоняю диалог (MyDialogId) из метода handleMessage (myMessage) из моего обработчика.

До этого я вызвал showDialog в своем onCreate() - Method и попытался отклонить диалог в handle-Message. Почему это решило проблему, я не могу сказать.

Ответ 8

Я экспериментировал с той же проблемой. Я создавал AlertDialog и ProgressDialog внутри обратного вызова onCreateDialog() и показывал их из onCreate(). Создание этих диалогов непосредственно в onCreate (без использования onCreateDialog()) и отключение их в onPause() работало для меня! На основе https://stackoverflow.com/a/5693467/955619

Ответ 9

 private AlertDialog alert11 = null;
 public void gpsDialog(){
    if (alert11 == null || !alert11.isShowing()) {
        AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
        builder1.setMessage("GPS not On");
        builder1.setCancelable(true);

        builder1.setPositiveButton("Enable GPS",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {

                    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    MainActivity.this.startActivity(intent);
                    dialog.dismiss();
                }
            });

        builder1.setNegativeButton("Cancel", 
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });

    alert11 = builder1.create();

    alert11.show();

    }

}