активность, не вызывающая onDestroy () после finish () - PullRequest
5 голосов
/ 04 февраля 2012

У меня есть три вида деятельности, давайте назовем их ОДИН, ДВА и ТРИ. Начиная с первого действия, нажатие кнопки запускает второе действие. Начиная с действия ДВА, нажатие кнопки запускает действие ТРИ.

Достаточно просто.

Теперь для действия ТРЕТЬЕ требуется немного данных, доступных из приложения (которые могут быть, а могут и не быть). В методе THREE onResume() выполняется проверка данных, и операция завершается, если ее не существует, например:

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

    /* ... get data from app ... */

    if (data == null) {
        Toast.makeText(this, "Data not found", Toast.LENGTH_SHORT).show();
        finish();
        return;
    }

    /* ... other logic ... */
}

Когда data == null, ТРИ завершается, разрушается и возвращается к ДВА. Все хорошо. Теперь в ДВОЕ нажатие кнопки возврата вызывает finish() на ДВУХ, но ДВА никогда не вызывает onDestroy(). Пользователь возвращается в ОДИН просто отлично, но любое последующее намерение вернуться в ДВУ не работает, и никаких ошибок не выдается. TWO остается в состоянии, в котором он был завершен (и приостановлен), но никогда не уничтожается и в результате не может возобновиться.

Итак, почему ТРИ важны в этом случае? Если я удаляю вызов finish() в блоке кода выше и полагаюсь на «естественное» окончание ТРИ (с помощью кнопки «назад»), когда пользователь возвращается к ОДНОМУ, ДВЕ было правильно уничтожено.

Хорошо, вот где это действительно сбивает с толку ...

Оставив вызов finish() на месте, я могу облегчить зависание, запустив THREE непосредственно из ONE, а затем «естественно» завершить его (кнопка «назад»). После уничтожения ТРИ (во второй раз) открывается ДВА, как и ожидалось.

Все, что я прочитал, говорит, что со мной все будет в порядке, звоня по номеру finish() в onResume(). Но в этом случае он оставляет что-то в плохом состоянии и мешает мне уничтожить вызывающую активность в дальнейшем.

Идеи? или я вывернул твои мозги наизнанку?

EDIT:

Дальнейшие исследования обнаружили этот камень ...

Окружение вызова finish() в ТРИ с обработчиком postDelay() около 500 миллисекунд позволит TWO закрыться, как ожидается. Как это:

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

    /* ... get data from app ... */

    if (data == null) {
        Toast.makeText(this, "Data not found", Toast.LENGTH_SHORT).show();
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, 500);
        return;
    }

    /* ... other logic ... */
}

Не совсем мое представление об исправлении ...

Ответы [ 3 ]

2 голосов
/ 04 февраля 2012

действие не завершено / уничтожено при нажатии на спину.

Использование

 @Override
    public void onBackPressed()
    {
        finish();
    }
1 голос
/ 04 февраля 2012

Поскольку я не могу комментировать, я напишу здесь.

Я не уверен на 100%, следил ли я за тобой, но прямо в конце ты упоминаешь, что

После того, как ТРИ уничтожено(второй раз), ДВА открывается, как и ожидалось.

Что вы подразумеваете под этим, так как, если я правильно следил за вами, вы сказали, что вы открываете ДВУ с кнопкой в ​​ОДНОМ и ТРЕТЬЕ с кнопкой в ​​ДВЕ,Так как же ДВА может открыться, как ожидалось, или вы имеете в виду, что при выходе из него он переходит к onDestroy ()?

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

0 голосов
/ 04 февраля 2012

Так как эта проблема возникает только из onResume () [см. Комментарии], я бы сказал, что это звучит как проблема с сохранением состояния, а не с работой со стеком.

Посмотрите на этот вопрос о переполнении стека Сохранение состояния активности Android с помощью Save Instance State

Если onPause () вы сохраняете «данные» (я не знаю его тип объекта, как вы не сказали) в Bundle затем onResume () иди и получи его.

Еще один пример, найденный здесь Google, использует SharedPreferences вместо Bundle для достижения того же результата.

В целом это будет означать, что вы можете обрабатывать / предотвращать обнуление «данных», так как вы можете восстановить их, тем самым экономя усилия по уничтожению ТРИ и пытаясь возиться со стеком, просто соблюдая условия, сохраняя рабочий процесс «естественным».

...