2012-03-16 11 views
5

Znów pytanie o LocalServices. Jak mogę (ponownie) powiązać istniejącą usługę po onDestroy()?wiązanie z uruchomioną usługą (po zakończeniu())/wywoływacz Handler

Problem: Łączę się z usługą i uruchomieniem usługi z działania. Publikuję uruchamiane obiekty do segregatora, wywołanie zwrotne (aktualizowanie paska postępu) w interfejsie użytkownika. Po zamknięciu tej czynności system operacyjny może zakończyć cykl życia i zniszczyć działanie, wywołując funkcję Destroy(), prawda? Symuluję to, wywołując metodę finish() w metodzie onPause(). Więc kiedy ponownie uruchomię działanie, jak ponownie połączyć się z usługą SAME? Myślałem, że Usługi to Singelton, ale kiedy próbuję ponownie się połączyć, otrzymuję inne odniesienie do segregatora. Tak więc binder.callbackHandler.post(binder.progressHandler); nadal ma odniesienie do starego bindera/callback/progressHandler, a nie do mojego nowego. Nawet konstruktor usługi jest ponownie wywoływany!

Czy istnieje jakieś rozwiązanie, aby mieć pasek postępu, aktualizowany przez obiekty wywołania zwrotnego z usługi (działa). Zamykanie/onDestroy() działanie. Wróć i kontynuuj pasek postępu?

Mój kod jest dość duży, ale odtworzył 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! 
        } 
     } 
} 

Odpowiedz

8

mam go teraz. Rozwiązaniem jest jawne wywołanie startService(serviceIntent); przed wiążą się w Usłudze przy użyciu getApplicationContext().bindService(serviceIntent,mTestServiceConnection, Context.BIND_AUTO_CREATE);

Powód: Po uruchomieniu usługa z bindService(), staje oprawionego usługowym

działa tylko tak długo, jak innej aplikacji składnik jest z nim związany.

Jeśli uruchomić usługę z startService() może

może działać w tle na czas nieokreślony,

Więc jeśli masz np pasek postępu w interfejsie użytkownika i chcesz go kontynuować aktualizację, powinieneś uruchomić usługę, a następnie powiązać i cofnąć powiązanie w onResume()/onPause(). Ale bądź niezręczny: od momentu ręcznego uruchomienia usługi, Powinieneś również zatrzymać to ręcznie. Najprostszym sposobem jest zadzwonić pod numer stopSelf() po wykonaniu usługi.

Ta dusza obejmuje prawidłowe wiązanie z działalności z np. pasek postępu do tej samej usługi nawet po zniszczeniu działania lub po zmianie orientacji.

+0

pracował dla mnie. Pamiętaj tylko, że jeśli używasz getApplicationContext() podczas wiązania, użyj go ponownie, gdy usuniesz powiązanie. – fersarr

Powiązane problemy