studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android handler

para - manual de programacion android pdf



Cómo funcionan las clases de manejador en Android (3)

Puedes ver la documentation .

Pero para comprender los documentos, primero debe comprender varios conceptos: Mensaje, Cola de mensajes, Controlador y Looper , y su relationship .

Lo siguiente ilustra cómo funciona Looper, muestra que el looper es un objeto local de hilo y su relación con MessageQueue:

class Looper{ public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } msg.target.dispatchMessage(msg); msg.recycle(); } } } }

Varios comentarios:

Looper es un objeto local de subproceso tal que cada subproceso tiene un looper. Cada looper está asociado con una cola de mensajes. El looper obtiene continuamente los mensajes ("tareas", "comandos" o como quieras llamarlos) desde la cola, y envía el mensaje a su destino, que es un controlador para manejar ese mensaje (por ejemplo, devolviendo un Runnable contenido en el mensaje). Cuando no quedan mensajes en la cola, el hilo se bloquea hasta que haya nuevos mensajes. Para detener un Looper, tiene que llamar a quit () en él (lo que probablemente no detiene el bucle de inmediato, sino que establece un indicador privado que se verifica periódicamente desde el bucle, indicando que se detenga).

El marco de Android proporciona la clase Handler para simplificar las cosas. Cuando creas una instancia de Handler, está vinculada (de forma predeterminada) al Looper que ya está adjunto al hilo actual. (El manejador sabe a qué Looper se debe adjuntar porque antes llamamos a prepare (), que almacenaba una referencia al Looper en un ThreadLocal).

Con un controlador, solo puede llamar a post () para "poner un mensaje en la cola de mensajes del hilo" (por así decirlo). El manejador se encargará de todo lo relacionado con la devolución de llamadas de IdleHandler y se asegurará de que se ejecuta su Runnable publicado. (También podría verificar si ya es el momento adecuado, si ha publicado con retraso).

El siguiente código muestra las formas típicas en que los usamos.

class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); }

}

Handler es ampliamente utilizado en los servicios de Android. Android compatible con la comunicación entre aplicaciones. Por lo general, cuando implementamos un servicio, que no necesita manejar subprocesos múltiples, implementamos un controlador que recibe una devolución de llamada para cada llamada de un cliente. Luego cree un objeto Messenger (referencia al Manejador), que es un objeto Binder y devuelva este objeto a los clientes cuando vinculen este servicio. Por lo tanto, el cliente puede usar este Messenger para enviar mensajes (a la cola de subprocesos locales, enviarlos al manejador a través de Looper) a este servicio y gestionarlos en el manejador. Ejemplo de código adjunto:

public class MessengerService extends Service { /** Command to the service to display a message */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } final Messenger mMessenger = new Messenger(new IncomingHandler()); @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); } }

Soy nuevo en Android y estaba leyendo las aplicaciones de demostración en el sitio web oficial de Android. Y me encontré con un método de la clase Handler llamado postDelayed(Runnable r, long milliseconds) .

¿Alguien puede explicar qué hace este método?


postDelayed (Runnable r, long delayMillis)

Hace que el Runnable r se agregue a la cola de mensajes, para que se ejecute después de que transcurra el tiempo especificado. El runnable se ejecutará en el subproceso al que se adjunta este controlador.

  • Ejecutable representa un comando que puede ejecutarse.

  • delayMillis representa el tiempo después del cual debe ejecutarse.

Básicamente, retrasa la ejecución del comando (quizás algún código) por un período de tiempo particular ( delayMillis ), para ejecutar el comando después del tiempo especificado.


public class ApiHandler { public static final String BASE_URL = "http://xxx.yyy/xx/"; private static final long HTTP_TIMEOUT = TimeUnit.SECONDS.toMillis(120); private static Webservices apiService; public static Webservices getApiService() { if (apiService == null) { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS); okHttpClient.setWriteTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS); okHttpClient.setReadTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS); RestAdapter restAdapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint(BASE_URL) .setClient(new OkClient(okHttpClient)) .setConverter(new GsonConverter(new Gson())) .build(); apiService = restAdapter.create(Webservices.class); /*RestAdapter.Builder builder = new RestAdapter.Builder(); builder.setConverter(new StringConverter()) .setEndpoint(BASE_URL) .setClient(new OkClient(new OkHttpClient())) .setLogLevel(RestAdapter.LogLevel.NONE); RestAdapter adapter = builder.build(); apiService = adapter.create(Webservices.class);*/ return apiService; } else { return apiService; } } }