Безопасно ли все очищать в onDestroy?

Конкретно: безопасно ли отменить задачу в onDestroy? Кроме того, безопасно ли использовать onDestroy для регистрации регистраторов и освобождения ресурсов?

Моя цель – убедиться, что моя задача отменена / уничтожена, когда действие уничтожено, но не раньше.

OnDestroy ():

  1. Вызывается, когда действие уничтожается и ресурсы должны быть освобождены.
  2. НЕ вызывается, когда активность уничтожается в спешке (когда система находится на низком уровне ресурсов и т. Д.).

Первый случай ясен: я делаю очистку в onDestroy, и никаких проблем не возникает. Второй случай – проблема. Когда активность уничтожается, а onDestroy пропускается (поэтому я не отменяю свою задачу), может случиться, что задача продолжает выполнение, а затем завершает работу и пытается обновить мертвую активность, поэтому приложение выйдет из строя?


Мы подошли к реальному вопросу:

  1. Когда активность убита и onDestroy пропущен, все ли прикреплено к этой Деятельности автоматически уничтожено? (Is onDestroy пропущен только в том случае, если все будет полностью уничтожено? Задачи, зарегистрированные приемники и т. Д.)
  2. Если onDestroy пропущен, значит ли это, что все приложение убито?

Давайте сосредоточимся на onDestroy (), потому что решение не находится в onPause () или onStop (). Аргументы:

  • OnStop () может быть пропущен, когда действие уничтожается, как и onDestroy
  • OnPause вызывается слишком рано и слишком часто, поэтому это не подходит для использования. Примеры:

Блокировка экрана : onPause может вызываться, когда экран устройства заблокирован . Очень часто это происходит как заставка, и пользователь сразу открывает его, потому что он стоит там, глядя на экран. Отмена задач и прекращение всего, что делает мое приложение в таком случае, только ухудшат работу пользователя. Я не хочу, чтобы мое приложение задыхалось и плохо себя вел из-за случайной «заставки».

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

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

Список загрузки : на втором экране есть список, который показывает данные из веб-службы. Данные загружаются за 4 секунды. Я использую AsyncTask, и я знаю, что я должен отменить, когда это необходимо. Он не должен отменяться в onPause, потому что он должен продолжать загрузку, когда пользователь переключается между экранами. Поэтому я хотел бы отменить его в onDestroy.

Может быть еще много примеров. Некоторые из них могут быть не совсем уместны по мнению каждого (вы можете даже предложить использовать службу вместо AsyncTask). Но идея важна, и все они имеют одинаковую идею : продолжайте выполнять работу, характерную для Activity, в то время как Activity приостановлена , но ENSURE, чтобы остановить ее, когда Activity уничтожена . (Не имеет значения, пользуюсь ли я AsyncTask или службой. В любом случае работа должна быть остановлена, когда действие уничтожено.)

PS Если ответ заключается в том, что очистить в onDestroy небезопасно , это будет означать, что инфраструктура Android требует от нас прекратить все, что мы делаем в onPause. И тогда я не увижу причин для использования onDestroy …

Я хотел бы направить вас к этому ребенку: http://developer.android.com/reference/android/content/ComponentCallbacks2.html#onTrimMemory (int)

По сути, он дает вам все места, где система считает полезным отменить задачи и очистить память:

Пожалуйста, внимательно изучите следующие два случая:

TRIM_MEMORY_UI_HIDDEN – процесс показывал пользовательский интерфейс и больше не делает этого.

TRIM_MEMORY_COMPLETE – процесс приближается к концу списка LRU в фоновом режиме.

Каковы случаи большей части того, что вы просили.

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

Этот метод значительно улучшил мою жизнь разработки в подобных случаях.

Если вам просто нужно выполнить некоторую очистку, независимо от того, как деятельность закрыта, вы должны иметь возможность использовать комбинацию onSaveInstanceState() и onDestroy() . Один из них следует назвать независимо от того, что. Возможно, в вашей деятельности есть boolean cleanupDone , который устанавливается, когда один из двух финишей.

Что касается сохранения пользовательских данных , посмотрите на Сохранение постоянного состояния :

Google предлагает

«Изменить на месте» модель пользователя

То есть: сохранить, как только пользователь создаст новые данные, самое позднее в onPause() . Это не означает, что вам нужно воссоздать данные в onResume() , просто чтобы он был сохранен.

Кстати: onStop() можно пропустить только на устройствах с предварительной сотой , то есть с июня 2015 года менее 6% всех устройств. Тем не менее, onSaveInstanceState() следует вызывать, если либо onDestroy() либо onStop() опущены.

Что касается андроида,

1 Когда ваши приложения выходят из строя, каждый ресурс, относящийся к нему, уничтожается.

2 Когда устройство изменит конфигурацию, в результате чего действие будет уничтожено и воссоздано.

3 Когда приложения, работающие в фоновом режиме и Android, убьют его из-за работы с низкой памятью

Кроме них, другой метод обратного вызова называется то есть

1, когда другая активность идет впереди, или ваше устройство блокируется .etc

Во всех случаях в соответствии с вашим требованием вы можете освободить все свои ресурсы в onDestroy и отменить Thread и Asyntask и остановить все сервисы и т. Д. Если вы хотите, чтобы ваша задача оставалась приостановленной и живой, а при вызове destroy вы можете сохранить конфигурацию и сохранить ее В то время как onCreate вызывается снова по ошибке null или нет.