Я выполняю операции удаленной выборки аудиофайлов и воспроизведения аудиофайлов в фоновом потоке, используя AsyncTask
. Индикатор Cancellable
выполнения отображается на время выполнения операции выборки.
Я хочу отменить / прервать AsyncTask
выполнение, когда пользователь отменяет (решает не выполнять) операцию. Как лучше всего поступить в таком случае?
android
android-asynctask
Самух
источник
источник
while(running)
на,while(!isCancelled())
как говорили другие здесь в комментариях.Если вы выполняете вычисления :
isCancelled()
периодически проверять .Если вы выполняете HTTP-запрос :
HttpGet
илиHttpPost
где-нибудь (например, публичное поле).cancel
звонитеrequest.abort()
. Это вызоветIOException
попадание в ваш файлdoInBackground
.В моем случае у меня был класс коннектора, который я использовал в различных AsyncTasks. Для простоты я добавил
abortAllRequests
к этому классу новый метод и вызвал этот метод сразу после вызоваcancel
.источник
HttpGet.abort()
из фонового потока, иначе вы получите файлandroid.os.NetworkOnMainThreadException
.cancel(true)
прерывать? Из документации:If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
HttpURLConnection.disconnect();
cancel(true)
. Я использовал его, и он работает.Дело в том, что вызов AsyncTask.cancel () вызывает только функцию onCancel в вашей задаче. Здесь вы хотите обработать запрос на отмену.
Вот небольшая задача, которую я использую для запуска метода обновления
источник
running
флаг. AsyncTask имеет внутренний флаг, который устанавливается, когда задача была отменена. Заменитьwhile (running)
наwhile (!isCancelled())
. developer.android.com/reference/android/os/… Итак, в этом простом случае вам не нужноonCancelled()
переопределять.Просто: не используйте расширение
AsyncTask
.AsyncTask
предназначен для коротких операций, которые быстро завершаются (десятки секунд) и поэтому не требуют отмены. «Воспроизведение аудиофайлов» не подходит. Вам даже не нужен фоновый поток для обычного воспроизведения аудиофайлов.источник
onPostExecute()
чтобы увидеть, следует ли вам продолжать работу.Единственный способ сделать это - проверить значение метода isCancelled () и остановить воспроизведение, когда он вернет true.
источник
Вот как я пишу свою AsyncTask,
ключевой момент - добавить Thread.sleep (1);
источник
Наша глобальная переменная класса AsyncTask
И действие KEYCODE_BACK, которое прерывает AsyncTask
Меня устраивает.
источник
Я не люблю принудительно прерывать мои асинхронные задачи без
cancel(true)
необходимости, потому что у них могут быть ресурсы, которые нужно освободить, например, закрытие сокетов или файловых потоков, запись данных в локальную базу данных и т. Д. С другой стороны, я сталкивался с ситуациями, в которых Задача async отказывается завершать себя часть времени, например, иногда, когда основное действие закрывается, и я запрашиваю завершение задачи async изнутриonPause()
метода действия. Так что дело не в простом звонкеrunning = false
. Мне нужно найти смешанное решение: оба вызываютrunning = false
, затем дают асинхронной задаче несколько миллисекунд для завершения, а затем вызывают либоcancel(false)
илиcancel(true)
.Как побочный результат, после
doInBackground()
финиша иногдаonCancelled()
вызывается метод, а иногдаonPostExecute()
. Но как минимум гарантировано завершение асинхронной задачи.источник
Ссылаясь на ответ Янченко от 29 апреля 2010 г .: Использование подхода «пока (выполняется)» удобно, когда ваш код под «doInBackground» должен выполняться несколько раз во время каждого выполнения AsyncTask. Если ваш код в doInBackground должен выполняться только один раз за выполнение AsyncTask, перенос всего вашего кода в doInBackground в цикл while (running) не остановит выполнение фонового кода (фонового потока), когда Сам AsyncTask отменяется, потому что условие while (running) будет оценено только после того, как весь код внутри цикла while будет выполнен хотя бы один раз. Таким образом, вы должны либо (а.) Разбить свой код в разделе «doInBackground» на несколько блоков «пока (выполняется)» или (б.) Выполнить множество «isCancelled».https://developer.android.com/reference/android/os/AsyncTask.html .
Таким образом, для варианта (а) ответ Янченко можно изменить следующим образом:
Для варианта (b.) Ваш код в doInBackground будет выглядеть примерно так:
источник