Действия по уничтожению Android, процессы уничтожения

117

Привет, мне интересно, как Android управляет памятью, и я нигде не могу найти точного ответа. Предположим, у меня есть приложение с 5 действиями в текущем стеке действий (4 остановлены и 1 возобновлен), служба не подключена. Я нажимаю кнопку HOME, чтобы остановить все мои действия. Я запускаю другое приложение, потребляющее память, и общий объем памяти устройства начинает заканчиваться. И вопрос в том

... Что будет с моим приложением?

  1. Может ли система уничтожить только одно или несколько моих действий для восстановления памяти?
  2. Система убьет весь процесс моего приложения? Будет ли вся деятельность уничтожена?
  3. Что произойдет, когда я вернусь к своему приложению, когда оно было полностью убито? Будет ли он начинаться с самого начала (как при первом запуске) или будет пытаться восстановить действия до предыдущего состояния / если да, то только одно из них находится на вершине стека или все?

ОБНОВИТЬ:

Прежде чем задать этот вопрос, я несколько раз видел жизненный цикл Activity, но у него нет ответов на мои вопросы. Я сделал несколько тестов и у меня есть ответы. «Остановить процесс» в DDMS было ключом к тестированию.

Я не тестировал ответ на вопрос 1, но, как сказано в руководстве:

Если действие приостановлено или остановлено, система может удалить действие из памяти, либо попросив его завершить, либо просто завершив его процесс.

Кажется, что одно или несколько действий можно аккуратно уничтожить (с помощью метода onDestroy), не прерывая процесс. Вы просто получите (onCreate + bundle), когда вернетесь к ним.

Ответ на вопрос 2:

ДА. Обычно система убивает весь процесс, это означает, что все данные, включая действия и статические поля, уничтожаются. Это НЕ сделано хорошо - вы не получите onDestroy или finialize () ни для одной из ваших приостановленных / остановленных операций. Вот почему saveInstanceState () вызывается непосредственно перед методом onPause. onPause - это, по сути, последний метод, в котором вы должны что-то сохранить, потому что после этого метода вы никогда не увидите onStop или onDestroy. Система может просто убить процесс, уничтожив все ваши объекты, что бы они ни держали и что бы они ни делали.

Вопрос 3 ответ:

Что будет, когда вы вернетесь к убитому приложению?

  • До Android 2.2 - приложение будет запускаться с самого начала, с активностью запуска.
  • Начиная с версии 2.2 - система восстановит предыдущее состояние приложения. Что это означает? Это означает, что будет воссоздано последнее видимое действие (пакет onCreate +). Что будет со стеком активности? Стек в порядке, но все действия на нем мертвы. Каждый из них будет воссоздан (пакет onCreate +), когда вы вернетесь к нему с помощью кнопки возврата. И еще кое-что:

Обычно система очищает задачу (удаляет все действия из стека над корневым действием) в определенных ситуациях, когда пользователь повторно выбирает эту задачу на главном экране. Обычно это делается, если пользователь не посещал задачу в течение определенного времени, например 30 минут.

Вывод?

  1. Не думайте, что проблемы с обработкой ротации действий можно решить с помощью android: configChanges = "Ориентация". Когда вы сделаете это, вы столкнетесь со многими другими проблемами, о которых даже не подозреваете.
  2. Протестируйте свое приложение с помощью DDMS - кнопка «Остановить процесс». Посмотри это
  3. Будьте осторожны при использовании статических переменных. Не думайте, что когда вы инициализируете их в действии 1 - они будут инициализированы в действии 2. Единственным безопасным местом для инициализации глобальной статики будет класс Application.
  4. Помните, что вы никогда не увидите onStop или onDestroy. Закройте файлы / базы данных, остановите загрузчиков в onPause. Если вы хотите, чтобы приложение что-то делало в BG - используйте службу переднего плана.

Вот и все ... Надеюсь, я помог с моим эссе :)

отметка
источник
По вашему предположению, эти 5 действий происходят из одного приложения или из нескольких разных приложений?
dumbfingers
1
«У меня есть приложение с 5 действиями в текущем стеке действий» Конечно, все они из моего, одного и того же приложения процесса.
Марк
4
Спасибо, это был именно мой вопрос ... Ваш вопрос и ответы мне очень помогли.
craigrs84
@Mark: Сейчас эта проблема решена? А если да?
Амир Моавиа

Ответы:

30

Сначала взгляните на это:

img1

onPause () Вызывается, когда система собирается возобновить предыдущее действие. Обычно это используется для фиксации несохраненных изменений в постоянных данных, остановки анимации и других вещей, которые могут потреблять ресурсы ЦП и т. Д. Реализации этого метода должны быть очень быстрыми, потому что следующее действие не будет возобновлено, пока этот метод не вернется. За ним следует либо onResume (), если действие возвращается на передний план, либо onStop (), если оно становится невидимым для пользователя.

onStop () Вызывается, когда действие больше не отображается для пользователя, потому что другое действие было возобновлено и перекрывает это. Это может произойти либо из-за того, что запускается новое действие, либо из-за того, что существующее передается перед этим, либо из-за того, что оно уничтожается. За ним следует либо onRestart (), если это действие возвращается для взаимодействия с пользователем, либо onDestroy (), если это действие прекращается.

Таким образом, при нажатии кнопки «HOME» на устройстве, текущая активность переднего плана ставится на onPause()то onStop(), другой 4 должен оставатьсяonStop()

Согласно документам Google:

  • Если действие находится на переднем плане экрана (вверху стека), оно активно или выполняется.
  • Если действие потеряло фокус, но все еще отображается (т. Е. Новое не полноразмерное или прозрачное действие сосредоточено в верхней части вашего действия), оно приостанавливается. Приостановленное действие является полностью активным (оно сохраняет всю информацию о состоянии и членах и остается подключенным к оконному менеджеру), но может быть прекращено системой в ситуациях с крайне низким объемом памяти.
  • Если действие полностью скрыто другим действием, оно прекращается. Он по-прежнему сохраняет всю информацию о состоянии и членах, однако он больше не виден пользователю, поэтому его окно скрыто, и оно часто будет отключено системой, когда память понадобится в другом месте.
  • Если действие приостановлено или остановлено, система может удалить действие из памяти, либо попросив его завершить, либо просто завершив его процесс. Когда он снова отображается для пользователя, его необходимо полностью перезапустить и вернуть в предыдущее состояние.

И для жизненного цикла процесса:

Жизненный цикл процесса 3. Фоновая активность (деятельность, которая не видна пользователю и была приостановлена) больше не является критичной, поэтому система может безопасно завершить свой процесс, чтобы освободить память для других процессов переднего плана или видимых процессов. Если его процесс необходимо убить, когда пользователь возвращается к действию (делая его снова видимым на экране), его метод onCreate (Bundle) будет вызван с сохраненнымInstanceState, который он ранее предоставил в onSaveInstanceState (Bundle), чтобы он может перезапустить себя в том же состоянии, в котором пользователь оставил его последним.

Все приведенные выше цитаты взяты из: Справочник разработчиков Android: Activity

Подтверждено, что система может уничтожать неактивные действия и повторно использовать память, когда вы запускаете некоторые приложения, потребляющие память. И вы можете реализовать что-то вроде: isFinishing()в своей деятельности, а затем с помощью кнопки «убить» в DDMS, чтобы определить, какие из ваших действий удаляются системой. Но я думаю, что система сначала уничтожит самую старую. Однако нет смысла продолжать другие действия после повторного использования «Действия запуска».

ОБНОВИТЬ

Вот несколько мнений, которые я нашел отсюда :

Остановленное состояние

Когда действие не отображается, но все еще находится в памяти, мы говорим, что оно остановлено. Остановленная активность может быть возвращена на передний план, чтобы снова стать беговой деятельностью. Или его можно уничтожить и удалить из памяти.

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

Остановленные действия можно удалить из памяти в любой момент.

dumbfingers
источник
4
Документация по этому вопросу довольно запутанная, однако можно убить только весь процесс, а не отдельные компоненты (действия, службы и т. Д.). См .: stackoverflow.com/questions/7536988/…
greg7gkb
Этот вопрос должен быть обновлен информацией из ссылки на комментарий @ greg7gkb, вводящий в заблуждение
Люк Де Фео
1

Может ли система уничтожить только одно или несколько моих действий для восстановления памяти?

Да. Android убивает действия, выполняемые в фоновом режиме, когда требуется память. Убийство одного или всех может зависеть от некоторых условий. Например, приостановленный или остановленный экземпляр может заставить Android убить действие или сам процесс. Здесь, в разделе « Жизненный цикл активности», вы можете получить следующие баллы. Я рекомендую вам полностью просмотреть эту страницу. Это обязательно развеет ваши сомнения.

Если действие потеряло фокус, но все еще отображается (т. Е. Новое не полноразмерное или прозрачное действие сосредоточено в верхней части вашего действия), оно приостанавливается. Приостановленное действие является полностью активным (оно сохраняет всю информацию о состоянии и членах и остается подключенным к оконному менеджеру), но может быть прекращено системой в ситуациях с крайне низким объемом памяти.

Если действие полностью скрыто другим действием, оно прекращается. Он по-прежнему сохраняет всю информацию о состоянии и членах, однако он больше не виден пользователю, поэтому его окно скрыто, и оно часто будет отключено системой, когда память понадобится в другом месте.

Если действие приостановлено или остановлено, система может удалить действие из памяти, либо попросив его завершить, либо просто завершив его процесс. Когда он снова отображается для пользователя, его необходимо полностью перезапустить и вернуть в предыдущее состояние.


Система убьет весь процесс моего приложения? Будет ли вся деятельность уничтожена?

Деятельность относится к отдельному человеку, тогда как процесс относится к группе действий. Посмотрите на третий пункт выше, он убивает упомянутый процесс.


Что произойдет, когда я вернусь к своему приложению, когда оно было полностью убито?

Это похоже на перезагрузку. Опять же, третий пункт даст вам несколько ответов, напримерWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Получить более подробную информацию о памяти , связанном питании здесь .

Изменить:
все действия в приложении выполняются в одном процессе. Таким образом, когда процесс завершается, все действия, независимо от 5 или 10, будут остановлены, то есть перезапущены. Перезагрузка приведет к тому, что ваше приложение запустится с самого начала без сохраненных состояний.

Виней
источник
2
Я видел Activity Lifecycle как минимум 5 раз, но он не отвечает на мои вопросы. То, что вы сказали, будет означать, что мой процесс приложения будет убит - когда я вернусь в приложение, он будет восстановлен до своего предыдущего состояния. Итак, когда у меня было 5 остановленных действий ... все ли они умерли (вызвано onDestroy), когда процесс был убит? Когда я вернулся в свое приложение, были ли восстановлены все действия (пакет onCreate +) или только тот, который находится в верхней части стека (виден пользователю)?
Марк
1
Все действия в приложении выполняются в одном процессе. Таким образом, когда процесс завершается, все действия, независимо от 5 или 10, будут остановлены, то есть перезапущены. Перезагрузка приведет к тому, что ваше приложение запустится сначала без сохраненных состояний ..
Vinay
1
Практически верно, но не для 2.2 и выше. Смотрите мое ОБНОВЛЕНИЕ вверху страницы.
Марк
1
Нет, это неправда и никогда не было правдой.
Судя
2
@JJPA Android не может уничтожать отдельные Activity для освобождения памяти, он только уничтожает процессы. См. Ответ Дайанн Хакбор, члена основной группы Android, участвующего в реализации «убийцы нехватки памяти»: stackoverflow.com/a/7576275/1290264 .
bcorso