Handler vs AsyncTask vs Thread [cerrado]

382

Me confundí un poco sobre las diferencias entre Handlers, AsyncTasky Threadsen Android. He leído bastantes blogs y preguntas aquí en StackOverflow.

Handlerson 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.

AsyncTaskson 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.

Threadsin 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.

Alx
fuente
1
Vale la pena echarle un vistazo: Douglas Schmidt conferencia Android concurrencia y sincronización
Daniel F
99
"Los controladores son hilos de fondo": algunas de las respuestas más votadas también parecen ir en esa dirección. Pero eso es un error. A Handlerno 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.
JimmyB

Respuestas:

57

Como dice el Tutorial sobre el procesamiento en segundo plano de Android con controladores, AsyncTask y Loaders en el sitio de Vogella:

La Handlerclase se puede usar para registrarse en un hilo y proporciona un canal simple para enviar datos a este hilo.

La AsyncTaskclase 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 Threades básicamente el elemento central de multihilo que un desarrollador puede usar con la siguiente desventaja:

Si usa hilos Java, debe manejar los siguientes requisitos en su propio código:

  • Sincronización con el hilo principal si publica resultados en la interfaz de usuario
  • No hay valor predeterminado para cancelar el hilo
  • Sin agrupación de hilos predeterminada
  • No hay valores predeterminados para manejar los cambios de configuración en Android

Y con respecto a AsyncTask, como lo dice la Referencia del desarrollador de Android :

AsyncTaskpermite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase 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.

AsyncTaskestá diseñado para ser una clase de ayuda en todo Thready Handler , y no constituye un marco genérico de roscado. Las AsyncTasks deberían usarse idealmente para operaciones cortas (unos segundos como máximo). Si necesita mantener los subprocesos en ejecución durante largos períodos de tiempo, se recomienda encarecidamente que utilice las diversas API proporcionadas por el paquete java.util.concurrent, como Ejecutor, ThreadPoolExecutor y FutureTask.

Actualización de mayo de 2015: encontré una excelente serie de conferencias sobre este tema.

Esta es la Búsqueda de Google: Douglas Schmidt conferencia concurrencia y sincronización de Android

Este es el video de la primera conferencia en YouTube.

Todo esto forma parte del CS 282 (2013): Programación de sistemas para Android de la Universidad de Vanderbilt . Aquí está la lista de reproducción de YouTube

Douglas Schmidt parece ser un excelente profesor

Importante: si se encuentra en un punto en el que está considerando usarlo AsyncTaskpara 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 .

Daniel F
fuente
44
En esa serie de conferencias, este enlace lo llevará directamente a algunos ejemplos de hilos: youtu.be/4Vue_KuXfCk?t=19m24s
Agresor
353

Si miramos el código fuente, veremos AsyncTaskyHandler está escrito puramente en Java. (Sin embargo, hay algunas excepciones. Pero ese no es un punto importante)

Entonces no hay magia en AsyncTasko Handler. 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:

Thread t = Thread.currentThread();    
int id = t.getId();

¿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, AsyncTasky Handler?

AsyncTasky Handlerestán escritos en Java (internamente usan a Thread), por lo que todo lo que podemos hacer con Handlero AsyncTask, podemos lograrlo Threadtambién.

¿Qué puede Handlery AsyncTaskrealmente 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 Handlery AsyncTask. Estas clases hacen la mayor parte del trabajo por nosotros, solo necesitamos saber qué métodos anular.

La diferencia entre Handlery AsyncTaskes: usar AsyncTaskcuando el hilo de la persona que llama es un subproceso de interfaz de usuario . Esto es lo que dice el documento de Android:

AsyncTask permite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase 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

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á:

El controlador le permite enviar y procesar mensajes y objetos ejecutables asociados con MessageQueue de un hilo

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 cuandoHandler comunica, solo le da un mensaje al hilo de la persona que llama y esperará para procesar.

¿Complicado? Solo recuerde que Handlerpuede comunicarse con el hilo de la persona que llama de forma segura.

hqt
fuente
44
en realidad, asynctask también se basa en handler y futuretask, ver
Sumit
AsyncTask es esencialmente una clase auxiliar construida sobre Handler y Thread. developer.android.com/reference/android/os/AsyncTask.html . Mire el documento "AsyncTask está diseñado para ser una clase auxiliar sobre Thread and Handler". AsyncTask se lanza en API3 mientras que Handler existe desde API1.
hjchin
52

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 . AsyncTaskda varias devoluciones de llamada respectivas al subproceso de trabajo y subproceso principal.

Úselo para pequeñas operaciones de espera como las siguientes:

  1. Obtención de algunos datos de los servicios web y visualización sobre el diseño.
  2. Consulta de base de datos.
  3. Cuando te das cuenta de que la operación en ejecución nunca, nunca estará anidada.

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:

  1. Le permite hacer colas de mensajes.
  2. Programación de mensajes.

Thread:

Ahora es el momento de hablar sobre el hilo.

Thread es el padre de ambos AsyncTasky Handler. Ambos usan hilo internamente, lo que significa que también puede crear su propio modelo de hilo como AsyncTasky Handler, pero eso requiere un buen conocimiento de la implementación de subprocesos múltiples de Java .

Lavekush Agrawal
fuente
1
La API de AsyncTask está, de hecho, escrita con Futures, Handlers y Executors. Ver código fuente: grepcode.com/file_/repository.grepcode.com/java/ext/…
IgorGanapolsky
22

Un AsyncTaskse 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 a HandleroThread parece más apropiado.

Puede generar un fondo Thready pasar mensajes a su hilo principal utilizando el método Handler's post.

Eugene S
fuente
9

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 anularlo handleMessage()para procesar los mensajes. Para procesar Runable, puede usar el método post();Solo necesita una instancia de un controlador en su actividad.

Tu hilo puede publicar mensajes a través del método sendMessage(Message msg)o sendEmptyMessage.

AsyncTask

Si tiene una Activityque 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

Harshal Benake
fuente
6

Thread:

Puede usar el nuevo Threadpara 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 Handlerpermite enviar y procesar mensajes y Runnableobjetos asociados con un hilo MessageQueue. Cada Handlerinstancia está asociada con un solo hilo y la cola de mensajes de ese hilo.

Hay dos usos principales para un Handler:

  1. Para programar mensajes y ejecutables que se ejecutarán en algún momento en el futuro;

  2. Para poner en cola una acción que se realizará en un hilo diferente al suyo.

AsyncTask :

AsyncTaskpermite 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:

  1. Por defecto, una aplicación empuja todos los AsyncTaskobjetos 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 .

  2. AsyncTaskLos objetos también son los delincuentes más comunes para problemas de referencia implícita. AsyncTaskLos 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 HandlerThreadno es suficiente, puede optar porThreadPoolExecutor

Sin embargo, me gustaría tener una conexión de socket en servicio. ¿Debería ejecutarse en un controlador o un subproceso, o incluso en una AsyncTask? La interacción UI no es necesaria en absoluto. ¿Hay alguna diferencia en términos de rendimiento que yo uso?

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, por HandlerThreadlo 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 una HandlerThready obtén una Handlerdel looper de HandlerThread.

 HandlerThread handlerThread = new HandlerThread("SocketOperation");
 handlerThread.start();
 Handler requestHandler = new Handler(handlerThread.getLooper());
 requestHandler.post(myRunnable); // where myRunnable is your Runnable object. 

Si desea comunicarse con el hilo de la interfaz de usuario, puede usar un controlador más para procesar la respuesta.

final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Foreground task is completed:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

en tu Runnable, puedes agregar

responseHandler.sendMessage(msg);

Más detalles sobre la implementación se pueden encontrar aquí:

Android: tostadas en un hilo

Ravindra babu
fuente
5

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ás AsyncTasksea ​​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). AsyncTasks 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, los AsyncTasks 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 un AsyncTask.

Brian
fuente
gracias, ¿hay alguna razón por la que deba usar Threads en lugar de AsyncTasks? ¿O es más recomendable usarlo?
Alx
99
@AeroDroid En su ejemplo: "un tiempo simple (verdadero)", vinculará la CPU aquí a menos que agregue un estado de suspensión en el bucle. Esto es cierto para cualquier bucle sin fin. Si desea reducir el uso de la CPU debido a esta sobrecarga, suspenda el subproceso durante unos milisegundos al final del ciclo.
Error 454
1
@Error 454: ¡eso es interesante! Si tuviera que elegir un número apropiado para el tiempo de sueño, ¿sería entre 40 y 80 milisegundos?
Abhijit
66
@Abhijit De las cosas del juego que he hecho en SDL, simplemente agregar una suspensión de 10 ms al bucle fue suficiente para caer del 99% de la CPU a ~ 0 durante los estados inactivos.
Error 454
15
En realidad, developer.android.com/reference/android/os/AsyncTask.html dice: "AsyncTasks debería usarse idealmente para operaciones CORTA". ¡También debe usarlos con cuidado ya que el sistema puede descartarlos sin ejecutarlos!
type-a1pha
5

AsyncTaskestá 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. Use Handlerpara actualizar el subproceso de la interfaz de usuario.

cielo
fuente
2
public class RequestHandler {

    public String sendPostRequest(String requestURL,
                                  HashMap<String, String> postDataParams) {

        URL url;

        StringBuilder sb = new StringBuilder();
        try {
            url = new URL(requestURL);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(15000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);


            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getPostDataString(postDataParams));

            writer.flush();
            writer.close();
            os.close();
            int responseCode = conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                sb = new StringBuilder();
                String response;
                while ((response = br.readLine()) != null){
                    sb.append(response);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }

}
Krishna Kulat
fuente
1

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]

MyImageSearch

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:

  • Opción 1: Crear un hilo Looper [hilo extendido] - y seguir descargando imágenes secuencialmente en un hilo manteniendo este hilo abierto [looper.loop ()]
  • Opción 2: utilice un conjunto de subprocesos y publique el ejecutable a través de myHandler que contiene referencias a mi ImageView, pero dado que las vistas en la vista de cuadrícula se reciclan, nuevamente puede surgir el problema cuando la imagen en el índice 4 se muestra en el índice 9 [la descarga puede toma mas tiempo]
  • Opción 3 [Utilicé esto]: utilice un conjunto de subprocesos y envíe un mensaje a myHandler, que contiene datos relacionados con el índice de ImageView y el propio ImageView, por lo que al hacer handleMessage () actualizaremos ImageView solo si currentIndex coincide con el índice de La imagen que intentamos descargar.
  • Opción 4: utilice AsyncTask para descargar las imágenes en segundo plano, pero aquí no tendré acceso a la cantidad de subprocesos que quiero en el grupo de subprocesos y varía con las diferentes versiones de Android, pero en la Opción 3 puedo tomar una decisión consciente del tamaño del grupo de subprocesos según la configuración del dispositivo que se utilice.

Aquí el código fuente:

public class MainActivity extends ActionBarActivity {

    GridView imageGridView;
    ArrayList<FlickrItem> items = new ArrayList<FlickrItem>();
    FlickrAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageGridView = (GridView) findViewById(R.id.gridView1);
        adapter = new FlickrAdapter(this, items);
        imageGridView.setAdapter(adapter);
    }

    // To avoid a memory leak on configuration change making it a inner class
    class FlickrDownloader extends AsyncTask<Void, Void, Void> {



        @Override
        protected Void doInBackground(Void... params) {
            FlickrGetter getter = new FlickrGetter();

            ArrayList<FlickrItem> newItems = getter.fetchItems();

            // clear the existing array
            items.clear();

            // add the new items to the array
            items.addAll(newItems);

            // is this correct ? - Wrong rebuilding the list view and should not be done in background
            //adapter.notifyDataSetChanged();

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            adapter.notifyDataSetChanged();
        }

    }

    public void search(View view) {
        // get the flickr data
        FlickrDownloader downloader = new FlickrDownloader();
        downloader.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Espero que mi respuesta, aunque larga, ayude a comprender algunos de los detalles más finos.

akshaymani
fuente
¿Puedo saber la razón por la cual mi explicación sobre la base de un ejemplo de analogía ha sido rechazada, para que yo también aprenda de ella?
akshaymani
2
En primer lugar, gracias por su respuesta, a pesar de que este tema es un poco antiguo, los conceptos centrales siguen estando actualizados. Mi pregunta inicial no se responde en absoluto, está dando un ejemplo y explica cómo funciona, pero las preguntas piden diferencias entre handler, asynctask y thread.
Alx
@ 80 hojas ok entiendo ahora, traté de explicar cómo llegué a la conclusión de elegir un camino sobre el otro. De todos modos, me encantaría conocer su opinión y la de otros sobre si lo que escribí es correcto o si se puede mejorar aún más.
akshaymani
1

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.

mani
fuente
0

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.

Arnav Rao
fuente
-1

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 controlador

AsyncTask- se utiliza para realizar aplicaciones de larga ejecución en un subproceso en segundo plano. Con n AsyncTaskpuede 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ón

arjun
fuente