Acceder al controlador de subprocesos de UI desde un servicio

Estoy intentando algo nuevo en Android para el que necesito acceder al manejador del hilo de la interfaz de usuario.

Sé lo siguiente:

  1. El subproceso de interfaz de usuario tiene su propio controlador y looper
  2. Cualquier mensaje se colocará en la cola de mensajes del hilo de la interfaz de usuario
  3. El looper recoge el evento y lo pasa al manejador
  4. El manejador maneja el mensaje y envía el evento específico a la interfaz de usuario

Quiero tener mi servicio que tiene que obtener el manejador de subprocesos de interfaz de usuario y poner un mensaje en este controlador. Para que este mensaje se procese y se envíe a la interfaz de usuario. Aquí el servicio será un servicio normal que será iniciado por alguna aplicación.

Me gustaría saber si esto es posible. Si es así, sugiérele algunos fragmentos de código para que pueda probarlo.

Saludos Girish

Este fragmento de código construye un Manejador asociado con el hilo principal (IU):

Handler handler = new Handler(Looper.getMainLooper()); 

A continuación, puede publicar elementos para su ejecución en el hilo principal (UI) de la siguiente manera:

 handler.post(runnable_to_call_from_main_thread); 

Si el controlador en sí se crea a partir del hilo principal (UI), el argumento puede omitirse por brevedad:

 Handler handler = new Handler(); 

La Guía de desarrollo de Android sobre procesos e hilos tiene más información.

Cree un objeto Messenger adjunto a su Handler y pase ese Messenger al Service (por ejemplo, en un Intent extra para startService() ). El Service puede enviar un Message al Handler través del Messenger . Aquí hay una aplicación de muestra que demuestra esto.

Por el momento prefiero usar la biblioteca de autobuses de eventos como Otto para este tipo de problema. Solo suscriba los componentes deseados (actividad):

 protected void onResume() { super.onResume(); bus.register(this); } 

Luego proporcione un método de callback:

 public void onTimeLeftEvent(TimeLeftEvent ev) { // process event.. } 

y luego cuando su servicio ejecute una statement como esta:

 bus.post(new TimeLeftEvent(340)); 

Ese POJO se transferirá a su actividad anterior y a todos los demás componentes de suscripción. Simple y elegante.

Puede obtener valores a través del receptor de transmisión …… de la siguiente manera: Primero cree su propio IntentFilter como,

 Intent intentFilter=new IntentFilter(); intentFilter.addAction("YOUR_INTENT_FILTER"); 

Luego crea la clase interna BroadcastReceiver como,

  private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { /** Receives the broadcast that has been fired */ @Override public void onReceive(Context context, Intent intent) { if(intent.getAction()=="YOUR_INTENT_FILTER"){ //HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW/////////// String receivedValue=intent.getStringExtra("KEY"); } } }; 

Ahora registre su receptor de difusión en onResume () como,

 registerReceiver(broadcastReceiver, intentFilter); 

Y finalmente anule el registro de BroadcastReceiver en onDestroy () como,

 unregisterReceiver(broadcastReceiver); 

Ahora, la parte más importante … Debes activar la transmisión desde donde necesites enviar valores … así que haz lo que quieras,

 Intent i=new Intent(); i.setAction("YOUR_INTENT_FILTER"); i.putExtra("KEY", "YOUR_VALUE"); sendBroadcast(i); 

…. aplausos 🙂

Solución:

  1. Crear un controlador con Looper desde el hilo principal: requestHandler
  2. Cree un Handler con Looper desde Main Thread: responseHandler y anule el método handleMessage
  3. publicar una tarea ejecutable en requestHandler
  4. Dentro de la tarea Runnable , llame a sendMessage en responseHandler
  5. Esta sendMessage resultado sendMessage de handleMessage en responseHandler.
  6. Obtener atributos del Message y procesarlo, actualizar la interfaz de usuario

Código de muestra:

  /* Handler from UI Thread to send request */ Handler requestHandler = new Handler(Looper.getMainLooper()); /* Handler from UI Thread to process messages */ final Handler responseHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { /* Processing handleMessage */ Toast.makeText(MainActivity.this, "Runnable completed with result:"+(String)msg.obj, Toast.LENGTH_LONG) .show(); } }; for ( int i=0; i<10; i++) { Runnable myRunnable = new Runnable() { @Override public void run() { try { /* Send an Event to UI Thread through message. Add business logic and prepare message by replacing example code */ String text = "" + (++rId); Message msg = new Message(); msg.obj = text.toString(); responseHandler.sendMessage(msg); System.out.println(text.toString()); } catch (Exception err) { err.printStackTrace(); } } }; requestHandler.post(myRunnable); }