Android: как аккуратно дождаться завершения AsyncTask после cancel()?

Ситуация: Activity запускает AsyncTask, который должен загрузить документ с веба и распарсерить его. Предусмотрена кнопка «отменить», которая должна завешать задачу, вызывая cancel(). Плюс задача должна завершаться из onPause (грубо говоря, если Activity закрывается).


Поскольку после cancel() задача может не сразу проверить isCancelled() (например, из-за ожидания загрузки документа), может возникнуть ситуация, когда Activity уже закрылась, а задача еще выполняется и вызывает методы Activity из onCancelled (например, чтобы сохранить состояние на момент отмены или показать сообщение). Получится плохо, приложение упадет.


Чтобы избежать этого, хотелось бы после cancel() аккуратно дождаться завершения задачи. AsyncTask.get() не подходит — он в этой ситуации просто бросает CancellationException. Соответственно, нужен какой-то еще способ дождаться завершения AsyncTask не выходя из onPause или, как вариант, сообщить задаче, что дергать методы Activity из onCancelled уже нельзя (а если отмена была по кнопке, то можно и нужно). Пока идея одна — дергать Activity через статические методы, которые будут проверять, доступна ли она (в onCreate/onResume запоминать статический указатель на Activity, в onPause сбрасывать его в null, в статических методах, проверять).


Но этот способ как-то нехорошо попахивает. Не верится, что на этот случай не предусмотрено чего-то более стандартного. Может, кто-то подскажет, куда смотреть?


Кстати, ситуация усугубляется тем, что иногда последний onProgressUpdate отрабатывается уже после onCancelled, а уж он-то точно должен иметь доступ к Activity.
  • Вопрос задан
  • 5037 просмотров
Пригласить эксперта
Ответы на вопрос 1
У вас AsyncTask хранит ссылку на объект класса Activity, как вариант вы можете при завершении Activity (в onDestroy) удалять эту ссылку. Т.е. вы можете добавить метод в таску (аля removeLinkActivity), в котором обнулити ссылку на Activity, а в тех местах где этот активити используете просто сделаете проверку на null, т.е. если не null, то вызываем метод, если null, то нет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы