2011-07-06 8 views
8

Creé un servicio que sincroniza datos de la web en un hilo de fondo y desea notificar una actividad de la lista cuando el servicio se ha completado para que pueda actualizar su cursor? Cuál sería la mejor forma de hacer esto? Estoy pensando en enviar una transmisión cuando termine el servicio, pero no estoy seguro de si esa es la mejor manera de hacerlo. Necesito volver a consultar el cursor cuando el servicio ha terminado, así que no estoy seguro de si funcionará bien con los receptores de difusión. No he hecho un montón de Android por un tiempo así que gracias de antemano.Servicio de notificación de android actividad completada de la mejor manera?

Respuesta

15

Utilice un Handler en su servicio que registra un cliente cuando su ListActivity se conecta al servicio; es decir, en su método onServiceConnected en su ListActivity, envíe un Message a su servicio que le permite realizar un seguimiento de los clientes conectados. Luego, simplemente puede recorrer estos clientes en su Service y enviarles un Message cuando ocurra algo en su Service sobre el que desea notificar a su ListActivity. Para obtener más información, puede consultar el código en un proyecto mío en curso: mi ListActivity y mi Service stub.

En resumen, en su MainActivity, iniciar y unirse a su servicio con:

Intent i = new Intent(this, NetworkService.class); 
startService(i); 
bindService(i, networkServiceConnection, Context.BIND_AUTO_CREATE); 

Definir un mensajero para responder a los mensajes del servicio como:

Messenger messenger = new Messenger(new IncomingHandler()); 

class IncomingHandler extends Handler { 
    @Override 
    public void handleMessage(Message msg) { 
     switch (msg.what) { 
      case NetworkService.MSG_SOMETHING: 
       // do something here 
       break; 
      default: 
       super.handleMessage(msg); 
     } 
    } 
} 

y luego escribir su servicio código de conexión como:

private ServiceConnection networkServiceConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     networkService = new Messenger(service); 
     try { 
      Message msg = Message.obtain(null, NetworkService.MSG_REGISTER_CLIENT); 
      msg.replyTo = messenger; 
      networkService.send(msg); 
      log.debug("Connected to service"); 

     } catch (RemoteException e) { 
      // Here, the service has crashed even before we were able to connect 
     } 
    } 

Tenga en cuenta que el replyTo es el messenger que acabamos de crear.

En su NetworkService, realizar un seguimiento de clientes relacionados con:

ArrayList<Messenger> clients = new ArrayList<Messenger>(); 

y crear su manejador como:

class IncomingHandler extends Handler { 
     @Override 
     public void handleMessage(Message msg) { 
      switch (msg.what) { 
       case MSG_REGISTER_CLIENT: 
        log.debug("Adding client: " + msg.replyTo); 
        clients.add(msg.replyTo); 
        break; 
       default: 
        super.handleMessage(msg); 
        break; 
      } 
     } 
    } 

Entonces, cuando usted desea enviar un mensaje de vuelta a su MainActivity, justo haga algo como lo siguiente:

for (int i = 0; i < clients.size(); i++) { 
    try { 
     clients.get(i).send(Message.obtain(null, MSG_SOMETHING)); 
    } catch (RemoteException e) { 
     // If we get here, the client is dead, and we should remove it from the list 
     log.debug("Removing client: " + clients.get(i)); 
     clients.remove(i); 
    } 
} 
+0

Esto suena prometedor, todavía un poco confundido, pero creo que tendrá más sentido cuando intento implementarlo. ¿Hay alguna limitación en términos de tiempo de ejecución y cosas así como con los receptores de difusión? Te dejaré saber qué sucede cuando codigo esto. ¡Gracias! – marchinram

+0

No estoy seguro con respecto a 'BroadcastReceiver's, ya que esto no los usa, sino que usa' Messenger's y 'Handler's internos de la aplicación. Pero en mi experiencia, no he visto retrasos en la actualización de mi UI en función de un evento en mi 'Servicio'. ¡Espero que esto funcione para usted! – zeitkunst

5

Si ya está utilizando la biblioteca de soporte, podría fácilmente iniciar una transmisión desde el servicio utilizando el LocalBroadcastManager de vuelta a su actividad que escucharía la transmisión que se está enviando.

El uso de LocalBroadcastManager garantiza que solo su propia aplicación reciba la transmisión, por lo que no tiene que preocuparse por la filtración de datos privados o la apertura de potenciales agujeros de seguridad.

Véase también: how to use LocalBroadcastManager?

EDITAR (09/2014):

Una mejor manera de hacer esto sería utilizar un marco de autobuses evento como Otto (mi favorito) o GreenRobot/EventBus para evitar el acoplamiento de sus componentes demasiado apretado

0

Según The Busy Coder's Guide to Advanced Android Development

Un Event Bus es una gran manera para que el servicio para permitir que otras piezas de la aplicación sabe que ciertos trabajos se hizo. Proporciona un canal de comunicaciones estándar (o "bus") que los productores de eventos y los consumidores del evento pueden enganchar. Los productores de eventos simplemente necesitan entregar el evento al autobús; el autobús se encargará de dirigir esos eventos a los consumidores relevantes . Esto reduce el acoplamiento entre los productores y los consumidores , a veces incluso reduciendo la cantidad de código necesario para la fuente y sumidero de estos eventos.

Cuestiones relacionadas