2012-03-16 17 views
5

Nuevamente una pregunta acerca de LocalServices. ¿Cómo puedo (re) vincularme a un Servicio existente, después de onDestroy()?vinculando al servicio en ejecución (después del final())/callback Handler

El problema: Estoy vinculando a un servicio y comenzando el servicio de una actividad. Estoy publicando objetos ejecutables en el cuaderno, para una devolución de llamada (actualizando una barra de progreso) en la interfaz de usuario. Cuando cierro esta actividad, el sistema operativo puede finalizar el ciclo de vida y destruir la actividad, invocando a Destroy(), ¿verdad? Simulo esto, llamando a finish() en el método onPause(). Entonces, una vez que reinicie la Actividad, ¿cómo puedo enlazar al MISMO Servicio nuevamente? Pensé que los servicios son Singelton, pero cuando trato de volver a vincularme, obtengo otra referencia de enlace. Así que binder.callbackHandler.post(binder.progressHandler); todavía tiene la referencia a la antigua carpeta/callback/progressHandler, no a la nueva. ¡Incluso se llama nuevamente al Constructor del Servicio!

¿Hay alguna solución para tener una barra de progreso, actualizarse por objetos de devolución de llamada desde el servicio (en funcionamiento). Closing/onDestroy() la Actividad. Regresa, y continúa la barra de progreso?

Mi código es bastante grande, pero recreó el Szenario:

public class MyService extends Service { 
     private final LocalBinder binder = new LocalBinder(); 

     public class LocalBinder extends Binder implements TestRunServiceBinder { 
      private Handler callbackHandler; 
      private ServiceStartActivity.RunOnServiceProgress onProgress; 

      @Override 
      public void setActivityCallbackHandler(Handler messageHandler) { 
       callbackHandler = messageHandler; 
      } 

      @Override 
      public void setServiceProgressHandler(RunOnServiceProgress runnable) { 
       onProgress = runnable; 
      } 

       public void doSomething(){ 
        _doSomething(); 

     }; 

     private void _doSomething(){ 
     while(...){ 
      //do this a couple of times (could take up to 10min) 
      binder.callbackHandler.post(binder.progressHandler); 
      wait() 
     } 
     } 

    } 

_

public class ServiceStartActivity{ 
private final Handler messageHandler = new Handler(); 
    private ServiceConnection mTestServiceConnection = new ServiceConnection() { 


     @Override 
     public void onServiceDisconnected(ComponentName name) { 
      testRunBinder = null; 
     } 

     @Override 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      testRunBinder = (TestRunServiceBinder) service; 
      testRunBinder.setActivityCallbackHandler(messageHandler); 
      testRunBinder.setServiceProgressHandler(new RunOnServiceProgress()); 
     } 
     }; 

    @Override 
    protected void onStart() { 
    super.onStart(); 

    // bind to the Service 
    final Intent serviceIntent = new Intent(ServiceStartActivity.this, 
      MyService.class); 
    getApplicationContext().bindService(serviceIntent, 
      mTestServiceConnection, Context.BIND_AUTO_CREATE); 

    } 
    @Override 
    protected void onStop() { 
    super.onStop(); 
    getApplicationContext().unbindService(mTestServiceConnection); 
    } 
     public class RunOnServiceProgress implements Runnable { 
      @Override 
      public void run() { 
       //do something on the UI! 
        } 
     } 
} 

Respuesta

8

lo tengo ahora. La solución es llamada explícita startService(serviceIntent); antes de enlazar al Servicio utilizando getApplicationContext().bindService(serviceIntent,mTestServiceConnection, Context.BIND_AUTO_CREATE);

Motivo: Al iniciar un servicio con bindService(), se convierte en un servicio Bound una

carreras sólo mientras otra aplicación componente está ligado a eso.

Si se inicia un servicio con startService() puede

puede ejecutarse en segundo plano de forma indefinida,

tanto, si tiene, por ejemplo, una barra de herramientas en la interfaz de usuario, y desea que continúe actualizándola, debe iniciar su servicio y vincularlo y desvincularlo en Reanudar()/onPause(). Pero sea cuidadoso: desde que inició el Servicio manualmente, También debe detenerlo manualmente. La forma más sencilla de hacerlo es llamar al stopSelf() una vez que el Servicio haya realizado su trabajo.

Esta soultion cubre una encuadernación adecuada de una Actividad con, por ejemplo, una barra de progreso para el mismo Servicio incluso después de que se destruye la actividad o después de un cambio de orientación.

+0

funcionó para mí. Solo recuerde que si usa getApplicationContext() cuando se vincula, utilícelo de nuevo al desvincularlo. – fersarr

Cuestiones relacionadas