Стоит ли вызывать finish() после запуска нового действия в Android?

Нравиться:

startActivity(intent);
finish();

Без вызова finish() explicitly, onDestroy() не вызывается прежняя Activity, и у меня заканчивается память (OutOfMemory Exception).

Итак, стоит ли звонить finish() explicitly to prevent OutOfMemory Exception?


person Marton_hun    schedule 07.08.2013    source источник
comment
Что делать, если пользователь хочет вернуться к предыдущему действию, нажав кнопку «Назад»?   -  person Raghunandan    schedule 07.08.2013
comment
Нет. Ваша проблема в другом.   -  person fdreger    schedule 07.08.2013
comment
Используете ли вы Bitmap (или набор) где-нибудь? Если вы еще не использовали анализатор памяти mat, сейчас самое время.   -  person haventchecked    schedule 07.08.2013


Ответы (2)


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

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

Если вы переключаетесь между, скажем, действиями A и B, всегда запуская новое и никогда не вызывая finish(), это может вызвать исключение OOM, поскольку стек заполняется экземплярами каждого действия.

Подробнее об этом можно прочитать в разделе руководства Tasks and Back Stack< /а>. В нем также описывается, как правильно справляться с чередованием действий.

person Ted Hopp    schedule 07.08.2013
comment
Отличный ответ. Спасибо. - person stevehs17; 06.04.2016
comment
Имеет ли вообще значение порядок startActivity(intent); finish(); этих двух утверждений? - person Weishi Z; 02.09.2016
comment
@WeishiZeng - я делал это обоими способами, и, похоже, это не имеет значения. Я не думаю, что это имеет значение. - person Ted Hopp; 02.09.2016
comment
@TedHopp Спасибо! Я также видел, как оба работают. Но просто любопытно, возможно ли, что finish() приводит к уничтожению текущего экземпляра активности до того, как произойдет startActivity(intent)? Тогда это проблематично, поскольку и intent, и startActivity() не будут существовать без связанного с ними экземпляра. - person Weishi Z; 02.09.2016
comment
@WeishiZeng - я не думаю, что есть проблема. Действие может быть уничтожено (хотя это может произойти при последующем проходе цикла пользовательского интерфейса), но экземпляр объекта действия все еще существует. - person Ted Hopp; 03.09.2016
comment
@TedHopp Под уничтожением вы имеете в виду, что 1) вызывается onDestroy () и 2) удаляется из стека задач? Но экземпляр активности не подходит для gc? - person Weishi Z; 03.09.2016
comment
@WeishiZeng - Да, я имел в виду и то, и другое. Я не уверен, что onDestroy() вызывается немедленно, но это не должно иметь значения. Экземпляр действия не подходит для gc, потому что в системе есть ссылка на намерение, в котором есть ссылка на действие. Так что, что касается gc, экземпляр все еще жив. - person Ted Hopp; 04.09.2016

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

Однако я не уверен, что именно поэтому вы получаете исключение OOM, и вам, вероятно, следует выяснить, откуда оно взялось. Если вы используете Bitmaps, это может быть причиной исключения.

person codeMagic    schedule 07.08.2013
comment
Да, я использую битмапы. Без явного вызова finish() GC не вызывает onDestroy() Activity, а загруженные Bitmap-ресурсы Activity занимают много памяти, поэтому я получаю outOfMemoryException. Если onDestroy() не вызывается GC, означает ли это утечку памяти? Если нет ссылки на действие, не должен ли сборщик мусора вызывать ondestroy(), когда требуется больше памяти? - person Marton_hun; 07.08.2013