Handler vs AsyncTask

128

Estoy confundido sobre cuándo elegiría AsyncTask sobre un controlador. Digamos que tengo un código que quiero ejecutar cada n segundos que actualizará la interfaz de usuario. ¿Por qué elegiría uno sobre el otro?

Steve
fuente
1
Esto se ha vuelto más complicado con AsyncTaskLoaders. Consulte stackoverflow.com/q/7120813/969325 para obtener más información.
Warpzit

Respuestas:

75

En mi opinión, AsyncTask fue escrito para proporcionar una forma conveniente y fácil de usar para lograr el procesamiento en segundo plano en las aplicaciones de Android, sin preocuparse demasiado por los detalles de bajo nivel (hilos, bucles de mensajes, etc.). Proporciona métodos de devolución de llamada que ayudan a programar tareas y también a actualizar fácilmente la IU cuando sea necesario.

Sin embargo, es importante tener en cuenta que cuando se utiliza AsyncTask, un desarrollador se somete a sus limitaciones, lo que resultó de las decisiones de diseño que tomó el autor de la clase. Por ejemplo, recientemente descubrí que hay un límite en la cantidad de trabajos que se pueden programar con AsyncTasks.

El controlador es más transparente de los dos y probablemente te da más libertad; así que si quieres tener más control sobre las cosas, elegirías Handler; de lo contrario, AsynTask funcionará bien.

Samuh
fuente
Así es. Estaba usando AsyncTasks para todas las operaciones en segundo plano en mi proyecto. En algún momento comencé a alcanzar ese límite máximo de trabajos, por lo que mis tareas solo comenzarían después de que terminara otra. Al final tuve que cambiar toda mi estructura para dejar de usar asinctascos y evitar alcanzar esa limitación.
tbraun
55
Desde Honeycomb en adelante, AsyncTasksse ejecutan en un hilo, por lo que ya no hay paralelismo. Aún podría ejecutarlos en una Executorimplementación paralela .
MrSnowflake
63

Mi regla de oro sería:

  • Si está haciendo algo aislado relacionado con la interfaz de usuario, por ejemplo, descargando datos para presentarlos en una lista, continúe y utilícelos AsyncTask.

  • Si está realizando múltiples tareas repetidas, por ejemplo, descargando múltiples imágenes que se mostrarán ImageViews(como descargar miniaturas) después de la descarga, use una cola de tareas con Handler.

alexanderblom
fuente
El controlador está en el nivel de API 1 y ASYNCTASK en el nivel de API 3. ¿será obsoleto a cualquier costo? porque me estoy concentrando en portar aplicaciones de versiones anteriores a 2.2 y 2.3 ..
yokks 03 de
10
Ninguno de los dos quedará obsoleto en el corto plazo. El controlador nunca quedará en desuso ya que la interfaz de usuario está básicamente construida alrededor de él.
alexanderblom
¿No deberías usar un cargador para cargar datos para que tu UI los presente?
nbarraille
19

Siempre trate de evitar usar AsyncTask cuando sea posible principalmente por las siguientes razones:

  • No se garantiza que AsyncTask se ejecute ya que el sistema establece una base ThreadPool y un tamaño máximo establecido y si crea demasiado asinctask, eventualmente serán destruidos

  • AsyncTask se puede finalizar automáticamente, incluso cuando se ejecuta, dependiendo del ciclo de vida de la actividad y no tiene control sobre él

  • Los métodos AsyncTask que se ejecutan en el subproceso de interfaz de usuario, como onPostExecute, podrían ejecutarse cuando la actividad a la que se refiere, ya no es visible o posiblemente esté en un estado de diseño diferente, como después de un cambio de orientación.

En conclusión, no deberías usar los métodos vinculados a UIThread de AsyncTask, que es su principal ventaja. Además, solo debe hacer un trabajo no crítico en doInBackground. Lea este hilo para obtener más información sobre estos problemas:

¿AsyncTask tiene fallas conceptuales o simplemente me falta algo?

Para concluir, trate de preferir usar IntentServices, HandlerThread o ThreadPoolExecutor en lugar de AsyncTask cuando cualquiera de los problemas mencionados anteriormente pueda ser una preocupación para usted. Claro que requerirá más trabajo, pero su aplicación será más segura.

type-a1pha
fuente
Sí, he pasado mucho tiempo lamentando muchos usos de AsyncTasks. Parecen geniales, pero ... ¡tantos problemas!
SMBiggs
66
Lamento publicar tan en contra de sus puntos, pero no puedo dejar que su estilo deficiente afecte a los novatos a Android. Punto uno. NO deberías tener tantos hilos ejecutándose. Si te encuentras con esto, tu arquitectura es foobar. Punto 2. Cómo demonios ... De acuerdo, sí, todo en Android es un juego gratuito para el recolector de basura ... Solo verías un comportamiento absurdo como se describe anteriormente, en algunos casos estrictamente abusivos de tareas. Punto 3. Gestionar su tarea, para no ser grosero, es una habilidad novata. O lo matas cuando llamas a onPause, o lo desconectas y adjuntas adecuadamente como corresponde.
StarWind0
1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html Esto es todo lo que necesita para aprender cómo hacer las tareas correctamente sin los problemas anteriores (suponiendo que no esté haciendo algo como arrojar unos cientos de tareas)
StarWind0
16

Si desea hacer un cálculo cada x segundos, probablemente debería programar un Runnableen un Handler(con postDelayed()) y eso Runnabledebería comenzar en el hilo de la interfaz de usuario actual. Si desea iniciarlo en otro hilo, use HandlerThread. AsyncTask es más fácil de usar para nosotros, pero no mejor que el controlador.

MrSnowflake
fuente
7

El controlador está asociado con el hilo principal de la aplicación. maneja y programa mensajes y ejecutables enviados desde hilos de fondo al hilo principal de la aplicación.

AsyncTask proporciona un método simple para manejar subprocesos en segundo plano con el fin de actualizar la interfaz de usuario sin bloquearla mediante operaciones que requieren mucho tiempo.

La respuesta es que ambos se pueden usar para actualizar la interfaz de usuario desde subprocesos en segundo plano, la diferencia estaría en su escenario de ejecución. Puede considerar usar el controlador si desea publicar mensajes retrasados ​​o enviar mensajes a MessageQueue en un orden específico.

Puede considerar usar AsyncTask si desea intercambiar parámetros (actualizando la interfaz de usuario) entre el hilo principal de la aplicación y el hilo de fondo de una manera fácil y conveniente.

secretlm
fuente
3
Puede crear su propio controlador asociado con otro subproceso.
Aleksejs Mjaliks
El controlador no está necesariamente vinculado al subproceso principal (subproceso UI). Está vinculado al hilo en el que se instancia y maneja los mensajes o Runnable que llegan a esta cola de mensajes de hilo. También puede enviar objetos Message y Runnable a esta cola de mensajes de hilo.
azec-pdx
2

AsyncTaskpresume que hará algo en el hilo de la interfaz de usuario, después de que se termine el trabajo de fondo. Además, puede ejecutarlo solo una vez (después de esto, su estado es FINISHEDy obtendrá una excepción al intentar ejecutarlo una vez más). Además, la flexibilidad de usarlo no es mucha. Sí, puede usarlo THREAD_POOL_EXECUTORpara una ejecución paralela, pero el esfuerzo podría no ser digno.

Handlerno presupone nada, excepto el manejo de Runnables y Mensajes. Además, se puede ejecutar tantas veces como desee . Usted es libre de decidir a qué hilo debe estar conectado, cómo se comunica con otros controladores, tal vez producirlos HandlerThread. Por lo tanto, es mucho más flexible y adecuado para algunos trabajos repetidos.

Verifique diferentes tipos de Handlerejemplos aquí .

lomza
fuente
0

Son la mejor pregunta de entrevista que se hace. AsyncTask : se utilizan para descargar subprocesos de la interfaz de usuario y realizar tareas en segundo plano. Manipuladores - dosent Android tienen forma directa de comunicación entre la interfaz de usuario y el hilo de fondo. Los controladores deben usarse para enviar mensajes o ejecutarse a través de la cola de mensajes.

Por lo tanto, las AsyncTasks se usan cuando las tareas deben ejecutarse en segundo plano y los controladores se usan para la comunicación entre una interfaz de usuario y un subproceso en segundo plano.

saubhagya das
fuente
0

doInBackground : básicamente funciona en otro hilo. onPostExecute : publica los resultados en el subproceso de la interfaz de usuario y envía mensajes internamente al controlador del subproceso principal. El subproceso de la interfaz de usuario principal ya tiene un looper y un controlador asociados.

Básicamente, si tiene que hacer una tarea en segundo plano, use AsyncTask. Pero en última instancia, si algo necesita actualizarse en la interfaz de usuario, utilizará el controlador del hilo principal.

Shinoo Goyal
fuente