Более конкретно: безопасно ли размещать отмену задачи в onDestroy? Кроме того, безопасно ли использовать onDestroy для отмены регистрации получателей и освобождения ресурсов?
Моя цель - убедиться, что моя задача отменяется/уничтожается при уничтожении Activity, но не раньше.
при уничтожении():
- вызывается, когда активность уничтожается и ресурсы должны быть освобождены.
- НЕ вызывается, когда активность уничтожается в спешке (когда в системе мало ресурсов и т. д.).
Первый случай понятен: всю очистку делаю в onDestroy и проблем не возникает. А вот со вторым случаем проблема. Когда действие уничтожается, а onDestroy пропускается (поэтому я не отменяю свою задачу), может ли случиться так, что задание продолжает выполнение, затем завершается и пытается обновить мертвое действие, поэтому приложение вылетает?
Мы подходим к реальному вопросу:
- Когда действие уничтожается, а onDestroy пропускается, все, что связано с этим действием, автоматически уничтожается? (Пропускается ли onDestroy только в случае, что все будет полностью уничтожено? Задачи, зарегистрированные приемники и т. д.)
- Если onDestroy пропущен, означает ли это, что все приложение уничтожается?
Давайте сосредоточимся на onDestroy(), потому что решение не в onPause() или onStop(). Аргументы:
- onStop() может быть пропущен при уничтожении Activity, как и onDestroy
- onPause вызывается слишком рано и слишком часто, поэтому он не подходит для данного варианта использования. Примеры:
Блокировка экрана: onPause можно вызывать, когда экран устройства заблокирован. Очень часто это происходит как заставка и пользователь сразу разблокируется, потому что стоит и смотрит на экран. Отмена задач и остановка всего, что делает мое приложение, в таком случае только ухудшит работу пользователя. Я не хочу, чтобы мое приложение зависало и плохо себя вело только из-за случайной «заставки».
В примере приложения у меня есть два экрана, которые являются действиями. Пользователь может быстро переключаться между ними. В этом приложении пользователи склонны часто и быстро переключать экраны.
Навигация: на одном из экранов есть карта, которая получает обновления местоположения от системы. Он записывает точный графический журнал изменений местоположения (маршрута), поэтому его необходимо запускать постоянно, пока действие не будет закрыто. Обычно я регистрирую и отменяю регистрацию любых получателей в onResume и onPause. Однако это сделало бы приложение очень непригодным для использования, так как обновления на карте будут останавливаться каждый раз, когда пользователь уходит. Поэтому я хотел бы отменить регистрацию получателей в onDestroy.
Список загрузки. На втором экране есть список, в котором показаны данные из веб-службы. Загрузка данных занимает 4 секунды. Я использую AsyncTask и знаю, что должен отменить его при необходимости. Его не следует отменять в onPause, потому что он должен продолжать загружаться, пока пользователь переключается между экранами. Поэтому я хотел бы отменить его в onDestroy.
Примеров может быть еще много. Некоторые из них могут быть не совсем подходящими, по мнению всех (вы можете даже предложить использовать сервис вместо AsyncTask). Но идея важна, и все они имеют одну и ту же идею: продолжать выполнять работу, относящуюся к действию, в то время как действие приостановлено, но УБЕДИТЬСЯ, чтобы прекратить выполнение это происходит, когда действие уничтожается. (Неважно, использую ли я AsyncTask или службу. В любом случае работа должна быть остановлена при уничтожении действия.)
P.S. Если ответ заключается в том, что выполнять очистку в onDestroy небезопасно, это будет означать, что платформа Android требует от нас остановить все, что мы делаем в onPause. И тогда я бы не видел смысла использовать onDestroy...