Me confundí un poco sobre las diferencias entre Handlers
, AsyncTask
y Threads
en Android. He leído bastantes blogs y preguntas aquí en StackOverflow.
Handler
son subprocesos en segundo plano que le permiten comunicarse con la interfaz de usuario. La actualización de una barra de progreso, por ejemplo, debe hacerse a través de Handler
. Tiene la ventaja de utilizar controladores MessagingQueues
, por lo que si desea programar mensajes o actualizar varios elementos de la interfaz de usuario o realizar tareas repetitivas.
AsyncTask
son similares, de hecho, hacen uso de Handler
, pero no se ejecutan en el subproceso de la interfaz de usuario, por lo que es bueno para recuperar datos, por ejemplo, obtener servicios web. Más tarde puedes interactuar con la interfaz de usuario.
Thread
sin embargo, no puede interactuar con la interfaz de usuario, proporciona un subproceso más "básico" y se pierde todas las abstracciones de AsyncTask
.
Sin embargo, me gustaría tener una conexión de socket en servicio. Si esto se ejecuta en un controlador o un hilo, o incluso unAsyncTask
? La interacción UI no es necesaria en absoluto. ¿Hay alguna diferencia en términos de rendimiento que yo uso?
Mientras tanto, la documentación se ha mejorado considerablemente.
Handler
no es un hilo, y no ejecuta nada. Es solo un medio para pasar mensajes de forma segura desde un hilo a la cola de mensajes de otro hilo . Entonces, normalmente, (al menos) aún deben crearse dos subprocesos que luego pueden usar un controlador, pero el controlador no puede ejecutar nada por sí mismo.Respuestas:
Como dice el Tutorial sobre el procesamiento en segundo plano de Android con controladores, AsyncTask y Loaders en el sitio de Vogella:
La
Handler
clase se puede usar para registrarse en un hilo y proporciona un canal simple para enviar datos a este hilo.La
AsyncTask
clase encapsula la creación de un proceso en segundo plano y la sincronización con el hilo principal. También es compatible con el informe de progreso de las tareas en ejecución.Y a
Thread
es básicamente el elemento central de multihilo que un desarrollador puede usar con la siguiente desventaja:Y con respecto a
AsyncTask
, como lo dice la Referencia del desarrollador de Android :Actualización de mayo de 2015: encontré una excelente serie de conferencias sobre este tema.
Importante: si se encuentra en un punto en el que está considerando usarlo
AsyncTask
para resolver sus problemas de subprocesos, primero debe verificarReactiveX/RxAndroid
si hay un patrón de programación posiblemente más apropiado. Un muy buen recurso para obtener una descripción general es Learning RxJava 2 para Android, por ejemplo .fuente
Si miramos el código fuente, veremos
AsyncTask
yHandler
está escrito puramente en Java. (Sin embargo, hay algunas excepciones. Pero ese no es un punto importante)Entonces no hay magia en
AsyncTask
oHandler
. Estas clases nos hacen la vida más fácil como desarrolladores.Por ejemplo: si el Programa A llama al método A (), el método A () podría ejecutarse en un hilo diferente con el Programa A. Podemos verificarlo fácilmente mediante el siguiente código:
¿Por qué deberíamos usar un nuevo hilo para algunas tareas? Puedes buscarlo en google. Muchas razones, por ejemplo: levantar pesados, trabajos de larga duración.
Así que, ¿cuáles son las diferencias entre
Thread
,AsyncTask
yHandler
?AsyncTask
yHandler
están escritos en Java (internamente usan aThread
), por lo que todo lo que podemos hacer conHandler
oAsyncTask
, podemos lograrloThread
también.¿Qué puede
Handler
yAsyncTask
realmente ayudar?La razón más obvia es la comunicación entre el hilo del llamador y el hilo del trabajador. ( Subproceso de llamada : un subproceso que llama al subproceso de trabajo para realizar algunas tareas. Un subproceso de llamada no necesariamente tiene que ser el subproceso de interfaz de usuario). Por supuesto, podemos comunicarnos entre dos hilos de otras maneras, pero existen muchas desventajas (y peligros) debido a la seguridad del hilo.
Por eso debemos usar
Handler
yAsyncTask
. Estas clases hacen la mayor parte del trabajo por nosotros, solo necesitamos saber qué métodos anular.La diferencia entre
Handler
yAsyncTask
es: usarAsyncTask
cuando el hilo de la persona que llama es un subproceso de interfaz de usuario . Esto es lo que dice el documento de Android:Quiero enfatizar dos puntos:
1) Uso fácil del hilo de la interfaz de usuario (por lo tanto, usar cuando el hilo de la persona que llama es el hilo de la interfaz de usuario).
2) No es necesario manipular manejadores. (significa: puede usar Handler en lugar de AsyncTask, pero AsyncTask es una opción más fácil).
Hay muchas cosas en esta publicación que aún no he dicho, por ejemplo: qué es UI Thread o por qué es más fácil. Debe conocer algunos métodos detrás de cada clase y usarlos, comprenderá completamente la razón.
@: cuando lea el documento de Android, verá:
Esta descripción puede parecer extraña al principio. Solo necesitamos entender que cada hilo tiene cada cola de mensajes (como una lista de tareas), y el hilo tomará cada mensaje y lo hará hasta que la cola de mensajes esté vacía (al igual que terminamos nuestro trabajo y nos acostamos). Así que cuando
Handler
comunica, solo le da un mensaje al hilo de la persona que llama y esperará para procesar.¿Complicado? Solo recuerde que
Handler
puede comunicarse con el hilo de la persona que llama de forma segura.fuente
Después de mirar en profundidad, es sencillo.
AsyncTask
:Es una manera simple de usar un hilo sin saber nada sobre el modelo de hilo java .
AsyncTask
da varias devoluciones de llamada respectivas al subproceso de trabajo y subproceso principal.Úselo para pequeñas operaciones de espera como las siguientes:
Handler
:Cuando instalamos una aplicación en Android, crea un hilo para esa aplicación llamado MAIN UI Thread. Todas las actividades se ejecutan dentro de ese hilo. Según la regla del modelo de subproceso único de Android, no podemos acceder a los elementos de la interfaz de usuario (mapa de bits, vista de texto, etc.) directamente para otro subproceso definido dentro de esa actividad.
Un controlador le permite comunicarse con el hilo de la interfaz de usuario desde otros hilos de fondo. Esto es útil en Android ya que Android no permite que otros hilos se comuniquen directamente con el hilo de la interfaz de usuario. Un controlador puede enviar y procesar mensajes y objetos ejecutables asociados con MessageQueue de un hilo. Cada instancia de Handler está asociada con un solo hilo y la cola de mensajes de ese hilo. Cuando se crea un nuevo controlador, está vinculado a la cola de hilo / mensaje del hilo que lo está creando.
Es la mejor opción para:
Thread
:Ahora es el momento de hablar sobre el hilo.
Thread es el padre de ambos
AsyncTask
yHandler
. Ambos usan hilo internamente, lo que significa que también puede crear su propio modelo de hilo comoAsyncTask
yHandler
, pero eso requiere un buen conocimiento de la implementación de subprocesos múltiples de Java .fuente
Un
AsyncTask
se utiliza para hacer algunos cálculos en segundo plano y publicar el resultado en el hilo de la interfaz de usuario (con actualizaciones de progreso opcionales). Como no le preocupa la interfaz de usuario, entonces aHandler
oThread
parece más apropiado.Puede generar un fondo
Thread
y pasar mensajes a su hilo principal utilizando el métodoHandler
'spost
.fuente
Hilo
Android es compatible con hilos estándar de Java . Puede usar hilos estándar y las herramientas del paquete "
java.util.concurrent
" para poner acciones en segundo plano. La única limitación es que no puede actualizar directamente la IU desde un proceso en segundo plano.Si necesita actualizar la IU desde una tarea en segundo plano, debe usar algunas clases específicas de Android. Puede usar la clase "
android.os.Handler
" para esto o la clase "AsyncTask
"Manipulador
La clase "
Handler
" puede actualizar la IU. Un identificador proporciona métodos para recibir mensajes y para ejecutables. Para usar un controlador, debe subclasificarlo y anularlohandleMessage()
para procesar los mensajes. Para procesarRunable
, puede usar el métodopost();
Solo necesita una instancia de un controlador en su actividad.Tu hilo puede publicar mensajes a través del método
sendMessage(Message msg)
osendEmptyMessage
.AsyncTask
Si tiene una
Activity
que necesita descargar contenido o realizar operaciones que se pueden realizar en segundo planoAsyncTask
permite mantener una interfaz de usuario receptiva y publicar el progreso de esas operaciones para el usuario.Para más información puede echar un vistazo a estos enlaces.
http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/
http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask
fuente
Thread
:Puede usar el nuevo
Thread
para tareas en segundo plano de larga duración sin afectar el subproceso de interfaz de usuario. Desde Java Thread, no puede actualizar UI Thread.Dado que Thread normal no es muy útil para la arquitectura de Android, se han introducido clases auxiliares para threading.
Puede encontrar respuestas a sus consultas en Rendimiento de subprocesos página de documentación de .
Manejador :
A le
Handler
permite enviar y procesar mensajes yRunnable
objetos asociados con un hiloMessageQueue
. CadaHandler
instancia está asociada con un solo hilo y la cola de mensajes de ese hilo.Hay dos usos principales para un
Handler
:Para programar mensajes y ejecutables que se ejecutarán en algún momento en el futuro;
Para poner en cola una acción que se realizará en un hilo diferente al suyo.
AsyncTask :
AsyncTask
permite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase le permite realizar operaciones en segundo plano y publicar resultados en el subproceso de la interfaz de usuario sin tener que manipular subprocesos y / o controladores.Inconvenientes:
Por defecto, una aplicación empuja todos los
AsyncTask
objetos que crea en un solo hilo. Por lo tanto, se ejecutan en serie y, como con el hilo principal, un paquete de trabajo especialmente largo puede bloquear la cola. Debido a esta razón, use AsyncTask para manejar elementos de trabajo de menos de 5 ms de duración .AsyncTask
Los objetos también son los delincuentes más comunes para problemas de referencia implícita.AsyncTask
Los objetos también presentan riesgos relacionados con referencias explícitas.HandlerThread :
Es posible que necesite un enfoque más tradicional para ejecutar un bloque de trabajo en un subproceso de larga ejecución (a diferencia de AsyncTask, que debe usarse para una carga de trabajo de 5 ms ), y alguna capacidad para administrar ese flujo de trabajo manualmente. Un subproceso de controlador es efectivamente un subproceso de larga ejecución que toma el trabajo de una cola y opera en él.
ThreadPoolExecutor :
Esta clase gestiona la creación de un grupo de subprocesos, establece sus prioridades y gestiona cómo se distribuye el trabajo entre esos subprocesos. A medida que la carga de trabajo aumenta o disminuye, la clase gira o destruye más hilos para ajustarse a la carga de trabajo.
Si la carga de trabajo es mayor y solo
HandlerThread
no es suficiente, puede optar porThreadPoolExecutor
Dado que la interacción de la interfaz de usuario no es necesaria, no puedes utilizarla
AsyncTask
. Los hilos normales no son muy útiles y, porHandlerThread
lo tanto, es la mejor opción. Como debe mantener la conexión del socket, Handler en el hilo principal no es útil en absoluto. Crea unaHandlerThread
y obtén unaHandler
del looper deHandlerThread
.Si desea comunicarse con el hilo de la interfaz de usuario, puede usar un controlador más para procesar la respuesta.
en tu
Runnable
, puedes agregarMás detalles sobre la implementación se pueden encontrar aquí:
Android: tostadas en un hilo
fuente
En mi opinión, los hilos no son la forma más eficiente de hacer conexiones de socket, pero proporcionan la mayor funcionalidad en términos de ejecución de hilos. Digo eso porque, por experiencia, la ejecución de subprocesos durante mucho tiempo hace que los dispositivos sean muy activos e intensivos en recursos. Incluso un simple
while(true)
calentará un teléfono en minutos. Si dice que la interacción de la interfaz de usuario no es importante, quizásAsyncTask
sea bueno porque están diseñados para procesos a largo plazo. Esta es solo mi opinión al respecto.ACTUALIZAR
¡Por favor ignore mi respuesta anterior! Respondí esta pregunta en 2011 cuando tenía mucha menos experiencia en Android que ahora. Mi respuesta anterior es engañosa y se considera incorrecta. Lo dejo allí porque muchas personas lo comentaron a continuación y me corrigieron, y aprendí mi lección.
Hay muchas otras respuestas mejores en este hilo, pero al menos me daré una respuesta más adecuada. No hay nada de malo en usar un Java normal
Thread
; sin embargo, realmente debe tener cuidado con la forma en que lo implementa porque hacerlo mal puede ser muy intensivo en el procesador (el síntoma más notable puede ser el calentamiento de su dispositivo).AsyncTask
s son bastante ideales para la mayoría de las tareas que desea ejecutar en segundo plano (ejemplos comunes son E / S de disco, llamadas de red y llamadas de base de datos). Sin embargo, losAsyncTask
s no deben usarse para procesos particularmente largos que pueden necesitar continuar después de que el usuario haya cerrado su aplicación o puesto su dispositivo en espera. Yo diría que en la mayoría de los casos, cualquier cosa que no pertenezca al hilo de la interfaz de usuario, puede solucionarse en unAsyncTask
.fuente
AsyncTask
está diseñado para realizar una operación de no más de unos pocos segundos en segundo plano (no se recomienda para megabytes de descarga de archivos desde el servidor o calcular tareas intensivas de la CPU, como operaciones de E / S de archivos). Si necesita ejecutar una operación de larga duración, le recomendamos encarecidamente que use hilos nativos de Java. Java le ofrece varias clases relacionadas con hilos para hacer lo que necesita. UseHandler
para actualizar el subproceso de la interfaz de usuario.fuente
fuente
Permítanme intentar responder la pregunta aquí con un ejemplo :) - MyImageSearch [Consulte la imagen aquí de la pantalla principal de actividad - que contiene un texto de edición / botón de búsqueda / vista de cuadrícula]
Descripción de MyImageSearch : una vez que el usuario ingrese los detalles en el campo de edición de texto y haga clic en el botón de búsqueda, buscaremos imágenes en Internet a través de los servicios web proporcionados por flickr (solo necesita registrarse allí para obtener una clave / token secreto) - para la búsqueda, enviamos una solicitud HTTP y OBTENEMOS datos JSON en respuesta que contienen las URL de imágenes individuales que luego utilizaremos para cargar la vista de cuadrícula.
Mi implementación : en la actividad principal, definiré una clase interna que extiende AsyncTask para enviar la solicitud HTTP en el método doInBackGround y buscar la respuesta JSON y actualizar mi ArrayList local de FlickrItems que voy a usar para actualizar mi GridView a través del FlickrAdapter (extiende BaseAdapter) y llame al adapter.notifyDataSetChanged () en onPostExecute () de AsyncTask para volver a cargar la vista de cuadrícula. Tenga en cuenta que aquí la solicitud HTTP es una llamada de bloqueo por lo que lo hice a través de AsyncTask. Y puedo guardar en caché los elementos en el adaptador para aumentar el rendimiento o almacenarlos en la tarjeta SD. La cuadrícula que inflaré en el FlickrAdapter contiene en mi implementación una barra de progreso y una vista de imagen. A continuación puede encontrar el código de mainActivity que utilicé.
Responda a la pregunta ahora : una vez que tengamos los datos JSON para obtener imágenes individuales, podemos implementar la lógica de obtener las imágenes en segundo plano a través de controladores o subprocesos o AsyncTask. Debemos tener en cuenta que, dado que mis imágenes una vez descargadas deben mostrarse en la interfaz de usuario / subproceso principal, no podemos simplemente usar subprocesos, ya que no tienen acceso al contexto. En el FlickrAdapter, las opciones que se me ocurren:
Aquí el código fuente:
Espero que mi respuesta, aunque larga, ayude a comprender algunos de los detalles más finos.
fuente
Depende de cuál elegir se basa en el requisito
El controlador se usa principalmente para cambiar de otro hilo al hilo principal, el controlador está conectado a un bucle en el que publica su tarea ejecutable en la cola. Entonces, si ya está en otro hilo y cambia al hilo principal, entonces necesita manejar en lugar de una tarea asincrónica u otro hilo
Si el controlador creado en un hilo distinto del hilo principal que no es un bucleador no dará error a medida que se crea el hilo del mango, ese hilo debe convertirse en un bucleador
AsyncTask se usa para ejecutar código durante unos segundos que se ejecuta en el subproceso en segundo plano y da su resultado al subproceso principal ** * Limitaciones de AsyncTask 1. La tarea Async no está asociada al ciclo de vida de la actividad y se mantiene en ejecución incluso si su actividad se destruye mientras que el cargador no no tiene esta limitación 2. Todas las tareas asíncronas comparten el mismo hilo de fondo para la ejecución, lo que también afecta el rendimiento de la aplicación
Thread también se usa en la aplicación para el trabajo en segundo plano, pero no tiene ninguna devolución de llamada en el hilo principal. Si el requisito se adapta a algunos subprocesos en lugar de un subproceso y que necesitan asignar tareas muchas veces, entonces el ejecutor del grupo de subprocesos es una mejor opción.
fuente
Hilo
Cuando inicia una aplicación, se crea un proceso para ejecutar el código. Para utilizar eficientemente los recursos informáticos, los subprocesos se pueden iniciar dentro del proceso para que se puedan ejecutar varias tareas al mismo tiempo. Por lo tanto, los subprocesos le permiten crear aplicaciones eficientes mediante el uso eficiente de la CPU sin tiempo de inactividad.
En Android, todos los componentes se ejecutan en un solo hilo principal llamado. El sistema Android pone en cola las tareas y las ejecuta una por una en el hilo principal. Cuando se ejecutan tareas de larga ejecución, la aplicación deja de responder.
Para evitar esto, puede crear hilos de trabajo y ejecutar tareas en segundo plano o de larga ejecución.
Manipulador
Dado que Android utiliza el modelo de subproceso único, los componentes de la interfaz de usuario se crean sin subprocesos, lo que significa que solo el subproceso que creó debe acceder a ellos, lo que significa que el componente de la interfaz de usuario debe actualizarse solo en el subproceso principal. Como el componente de IU se ejecuta en el subproceso principal, las tareas que se ejecutan en subprocesos de trabajo no pueden modificar los componentes de la IU. Aquí es donde entra en escena Handler. El controlador con la ayuda de Looper puede conectarse a un nuevo hilo o hilo existente y ejecutar el código que contiene en el hilo conectado.
El controlador permite la comunicación entre subprocesos. Con el controlador, el subproceso en segundo plano puede enviarle resultados y el controlador que está conectado al subproceso principal puede actualizar los componentes de la interfaz de usuario en el subproceso principal.
AsyncTask
AsyncTask proporcionado por Android utiliza tanto el subproceso como el controlador para facilitar la ejecución de tareas simples en segundo plano y actualizar los resultados del subproceso en segundo plano al subproceso principal.
Consulte los grupos de subprocesos, controladores, asynctask y subprocesos de Android para obtener ejemplos.
fuente
Handler
- es medio de comunicación entre hilos. En Android se usa principalmente para comunicarse con el hilo principal creando y enviando mensajes a través del controladorAsyncTask
- se utiliza para realizar aplicaciones de larga ejecución en un subproceso en segundo plano. Con nAsyncTask
puede obtener la operación en un subproceso en segundo plano y obtener el resultado en el subproceso principal de la aplicación.Thread
- es un proceso ligero, para lograr la concurrencia y la máxima utilización de la CPU. En Android, puede usar hilo para realizar actividades que no toque la interfaz de usuario de la aplicaciónfuente