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

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

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

OnDestroy():

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

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


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

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

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

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

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

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

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

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

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

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

Ответ 1

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

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

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

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

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

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

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

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

Ответ 2

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

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

Google предлагает

"изменить на месте" модель пользователя

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

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

Ответ 3

Насколько я занимаюсь андроидом,

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

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

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

кроме этого, другой метод обратного вызова называется я e

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

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