Может ли Android остановить действие, не убивая весь процесс, пока приложение находится в фоновом режиме?

Мне интересно, может ли система Android убить активность без всего процесса приложения, пока приложение свернуто. Из документации Android мы знаем, что onDestroy вызывается только тогда, когда активность собирается быть уничтоженной, и системы гарантируют вызов этого метода всякий раз, когда она собирается убить активность, он не будет вызываться только в случае уничтожения всего процесса приложения.

Итак, представьте себе такую ​​ситуацию — вы отправляете приложение в фоновый режим (сворачиваете), и через некоторое время у ОС начинает заканчиваться память, и она решает убить активность, но, поскольку приложение в настоящее время приостановлено и не может выполнять код, это не так. может вызывать свой метод onDestroy, хотя гарантируется, что он будет вызываться перед уничтожением каждой активности.

Итак, такого рода рассуждения наводят меня на мысль, что, пока приложение находится в фоновом режиме, ОС может убить только весь процесс, но не некоторые конкретные действия. Верны ли мои рассуждения, или я что-то упустил?


person starwarrior8809    schedule 20.07.2020    source источник
comment
Это хороший вопрос. Он может сделать это, например, см. параметр разработчика «Не сохранять действия». Однако я не уверен, что он обычно делает, когда эта опция не включена.   -  person Ryan M    schedule 21.07.2020


Ответы (3)


Это правда: пока приложение находится в фоновом режиме, ОС может убить только весь процесс, но не некоторые конкретные действия.

person Marian Paździoch    schedule 20.07.2020
comment
Это правильный ответ, Android не убивает только определенные компоненты, он убивает весь процесс. Есть цитата инженера Google, если вы достаточно копаете.. - person Steve M; 21.07.2020
comment
@SteveM, MarianPaździoch Спасибо за ответы. Итак, в основном последнее подтверждение - пока приложение находится на переднем плане, ОС может либо уничтожить какую-то конкретную активность, либо убить весь процесс (не должно происходить так часто, когда приложение активно), чтобы освободить какой-то ресурс и когда приложение приостановлено, он может только убить весь процесс? - person starwarrior8809; 21.07.2020
comment
@starwarrior8809 starwarrior8809 Насколько мне известно, он убивает весь процесс только как метод управления памятью. Выбор «Не сохранять действия» в опции «Разработка» уничтожает их, как только пользователь покидает его, но на самом деле это просто инструмент отладки. - person Steve M; 21.07.2020
comment
Я согласен со Стивом. @starwarrior8809 - вы спросили о том, когда приложение работает в фоновом режиме, поэтому я ответил о фоновом режиме. Теперь вы спрашиваете о переднем плане? - person Marian Paździoch; 22.07.2020

Ваше рассуждение верно.

Если пользователь уходит от действия/приложения (например, нажимая кнопку «Домой»), считается, что действие находится в состоянии «Остановлено». (состояния «Несуществующий», «Остановлено», «Приостановлено» и «Возобновлено»). Если андроиду не хватает памяти и ему нужно убить некоторые процессы, он нацелится на те процессы, действия которых находятся в состоянии «Остановлено», и убьет весь процесс (а не действие). Более того, это будет не вежливо при этом и, следовательно, не вызовет метод onDestroy() активности.

Изменить следующие комментарии о путанице сохраненного состояния при смерти процесса:

Если процесс активности убит, система временно сохраняет набор настроек вне активности и, используя эти настройки, воссоздает активность при следующем запуске.

Например, непосредственно перед переходом в состояние «Остановлено» система вызывает onSaveInstanceState(Bundle) для действия, которое еще не завершено, и сохраняет это Bundle вне действия. Система также помнит, что процесс активности был остановлен, пока он не завершен. Используя эти два вместе с другими настройками (сохраненными вне действия), система воссоздает действие.

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

Это хорошая новость, почему? Потому что, если бы это было не так, разработчику пришлось бы вручную скрывать ключевые свойства состояния вне действий и восстанавливать их при перезапуске действий (это был бы кошмар)

person Super Symmetry    schedule 20.07.2020

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

Система никогда не уничтожает активность напрямую, чтобы освободить память. Вместо этого он убивает процесс, в котором выполняется действие, уничтожая не только действие, но и все остальное, работающее в этом процессе.

Это, а также наблюдения в реальном мире дают отрицательный ответ.

https://developer.android.com/guide/components/activities/activity-lifecycle#asem

person Steve M    schedule 20.07.2020
comment
из тех же документов: Однако, если система уничтожает действие из-за системных ограничений (таких как изменение конфигурации или нехватка памяти), то, хотя фактический экземпляр действия исчез, система помнит, что он существовал. Если пользователь пытается вернуться к действию, система создает новый экземпляр этого действия, используя набор сохраненных данных, описывающих состояние действия на момент его уничтожения. - person starwarrior8809; 21.07.2020
comment
@SuperSymmetry, но ключевой вопрос заключался в том, может ли система уничтожить активность, когда приложение находится в фоновом режиме. Если приложение находится в фоновом режиме, оно приостанавливается и не выполняет какой-либо код, поэтому система не может убить какую-то конкретную активность, поскольку она не может вызвать свой обратный вызов onDestroy, хотя гарантируется, что он будет вызываться перед уничтожением каждой активности. Такое рассуждение подразумевает, что система может уничтожить весь процесс приложения только тогда, когда приложение приостановлено. Опять же, извините за много вопросов - я пришел сюда из мира iOS, где все проще - person starwarrior8809; 21.07.2020
comment
@SuperSymmetry Либо я неправильно понял ваш ответ, либо вы неправильно поняли мой вопрос) Если все приложение свернуто и приостановлено (процесс не потребляет процессорное время), то как система может вызвать onDestroy - приложение не работает! Затем он должен разбудить приложение для вызова действий onDestroy , но я не уверен, что это работает таким образом. - person starwarrior8809; 21.07.2020
comment
@SuperSymmetry на iOS система дает приложению около 5 секунд для работы в фоновом режиме, а затем оно приостанавливается, я думаю, что-то подобное используется на Android. Приложение приостанавливается и не потребляет циклы ЦП, если вы явно не запрашиваете фоновое выполнение (например, с помощью службы). Но если приложение приостановлено, то как можно вызвать действия onDestroy? - person starwarrior8809; 21.07.2020