Estoy ejecutando operaciones remotas de recuperación de archivos de audio y reproducción de archivos de audio en un hilo en segundo plano usando AsyncTask
. Se Cancellable
muestra una barra de progreso durante el tiempo que se ejecuta la operación de búsqueda.
Quiero cancelar / abortar la AsyncTask
ejecución cuando el usuario cancela (decide en contra) la operación. ¿Cuál es la forma ideal de manejar un caso así?
android
android-asynctask
Samuh
fuente
fuente
while(running)
conwhile(!isCancelled())
como otros han dicho aquí en los comentarios.Si está haciendo cálculos :
isCancelled()
periódicamente.Si está haciendo una solicitud HTTP :
HttpGet
o enHttpPost
algún lugar (por ejemplo, un campo público).cancel
, llamerequest.abort()
. Esto hará queIOException
se arroje dentro de sudoInBackground
.En mi caso, tenía una clase de conector que usé en varias AsyncTasks. Para mantenerlo simple, agregué un nuevo
abortAllRequests
método a esa clase y llamé a este método directamente después de llamarcancel
.fuente
HttpGet.abort()
desde un hilo en segundo plano o obtendrá unandroid.os.NetworkOnMainThreadException
.cancel(true)
interrumpir la solicitud? De la documentación: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)
. Lo usé y funciona.La cuestión es que la llamada AsyncTask.cancel () solo llama a la función onCancel en su tarea. Aquí es donde desea manejar la solicitud de cancelación.
Aquí hay una pequeña tarea que utilizo para activar un método de actualización
fuente
running
bandera. AsyncTask tiene un indicador interno que se establece cuando se cancela la tarea. Reemplazarwhile (running)
conwhile (!isCancelled())
. developer.android.com/reference/android/os/… Entonces, en este caso simple, no necesitaonCancelled()
anular.Simple: no uses un
AsyncTask
.AsyncTask
está diseñado para operaciones cortas que terminan rápidamente (decenas de segundos) y por lo tanto no necesitan ser canceladas. La "reproducción de archivos de audio" no califica. Ni siquiera necesita un hilo de fondo para la reproducción normal de archivos de audio.fuente
onPostExecute()
para ver si debe seguir adelante con el trabajo.La única forma de hacerlo es verificando el valor del método isCancelled () y deteniendo la reproducción cuando devuelve verdadero.
fuente
Así es como escribo mi AsyncTask,
el punto clave es agregar Thread.sleep (1);
fuente
Nuestra variable de clase global AsyncTask
Y la acción KEYCODE_BACK que interrumpe AsyncTask
Esto funciona para mi.
fuente
No me gusta forzar la interrupción de mis tareas asíncronas
cancel(true)
innecesariamente porque pueden tener recursos para liberar, como cerrar sockets o flujos de archivos, escribir datos en la base de datos local, etc. Por otro lado, me he enfrentado a situaciones en las que el La tarea asíncrona se niega a terminar parte del tiempo, por ejemplo, a veces cuando se cierra la actividad principal y solicito que la tarea asíncrona termine desde dentro delonPause()
método de la actividad . Así que no se trata simplemente de llamarrunning = false
. Tengo que buscar una solución mixta: ambos llamanrunning = false
, luego dan a la tarea asíncrona unos milisegundos para que finalice, y luego llamancancel(false)
ocancel(true)
.Como resultado secundario, después de
doInBackground()
finalizar, a vecesonCancelled()
se llama al método y, a vecesonPostExecute()
. Pero al menos se garantiza la terminación de la tarea asíncrona.fuente
Con referencia a la respuesta de Yanchenko el 29 de abril de '10: Usar un enfoque 'while (running)' es bueno cuando su código bajo 'doInBackground' debe ejecutarse varias veces durante cada ejecución de AsyncTask. Si su código bajo 'doInBackground' tiene que ejecutarse solo una vez por ejecución de AsyncTask, envolver todo su código bajo 'doInBackground' en un ciclo 'while (running)' no detendrá la ejecución del código de fondo (subproceso de fondo) cuando el AsyncTask en sí se cancela, porque la condición 'while (en ejecución)' solo se evaluará una vez que todo el código dentro del ciclo while se haya ejecutado al menos una vez. Por lo tanto, debe (a.) Dividir su código en 'doInBackground' en múltiples bloques 'while (running)' o (b.) Realizar numerosos 'isCancelled'https://developer.android.com/reference/android/os/AsyncTask.html .
Para la opción (a.), Uno puede modificar la respuesta de Yanchenko de la siguiente manera:
Para la opción (b.), Su código en 'doInBackground' se verá así:
fuente