2012-05-29 10 views
7

Ich versuche Dienst von einem anderen Dienst wie folgt zu binden:Wann wird genau onServiceConnected für den begrenzten Dienst aufgerufen?

public class ServiceA extends Service { 
    private ServiceB mDataService; 
    private boolean mIsBound; 

    @Override 
    public void onCreate(){ 
     super.onCreate(); 
     doBindService(); 
     /* ... */ 
    } 

    @Override 
    public void onStart(final Intent intent, final int startId){ 
     /*...*/ 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 
     public void onServiceConnected(ComponentName className, IBinder service) {    
      mDataService = ((ServiceB.LocalBinder)service).getService(); 
     } 
     public void onServiceDisconnected(ComponentName className) {    
      mDataService = null; 
     } 
    }; 

    void doBindService() {   
     bindService(new Intent(ServiceA.this, ServiceB.class), mConnection, Context.BIND_AUTO_CREATE);   
     mIsBound = true; 
    } 

    void doUnbindService() { 
     if (mIsBound) {      
      unbindService(mConnection); 
      mIsBound = false; 
     } 
    }  
} 

Dies ist ein einfacher Code-Schnipsel, die ich von goolge der Proben nahm :) Der Code funktioniert gut und mDataService hält einen Verweis auf ServiceB Instanz, aber Es gibt eine Sache, die ich nicht verstehen konnte: Der Rückruf onServiceConnected wird nach dem Anruf an onStart aufgerufen. Wie ich auf der Android-Dokumentation sah, the callback is running on the main thread - aber kann ich darauf zählen, dass es in diesem Fall IMMER in dieser Reihenfolge passiert? onCreate -> onStart -> onServiceConnected?

Antwort

2

Ich würde mich nicht darauf verlassen. Dies hängt davon ab, ob ServiceA und ServiceB in demselben oder in verschiedenen Prozessen ausgeführt werden. Es hängt wahrscheinlich auch davon ab, ob ServiceB bereits gestartet wurde. Sie sollten Ihren Code schreiben, damit Sie nicht auf diese Abfolge von Ereignissen angewiesen sind.

12

Es hat sich in der offiziellen Entwickler Guide, eindeutig erklärt die Context.bindService() ist in der Tat ein asynchroner Aufruf nicht, dies auch erklären, warum ServiceConnection.onServiceConnected() als Callback implementiert wird. Schauen Sie sich die dev guide:

Ein Client an den Dienst binden, kann durch bindService() aufrufen. Wenn dies der Fall ist, muss eine Implementierung von ServiceConnection bereitgestellt werden, die die Verbindung mit dem Dienst überwacht. Die Methode bindService() gibt sofort ohne Wert zurück, aber wenn das Android-System die Verbindung zwischen dem Client und dem Dienst herstellt, ruft esServiceConnected() in der ServiceConnection auf, um den IBinder bereitzustellen, den der Client für die Kommunikation mit dem Dienst verwenden kann. an einem gewissen Punkt auf UI-Thread

ServiceConnection.onServiceConnected() in der Zukunft genannt wird (nicht unmittelbar nach Context.bindService() aufgerufen wird), sobald die Verbindung zu Dienst ordnungsgemäß eingerichtet.

+0

Yup. Und die folgenden sollten mit großen roten Buchstaben irgendwo angegeben werden: ** Blockieren Sie nicht Aktivität/Service-Starter-Thread während des Wartens auf Service-Verbindung! ** (Nun, blockieren Sie es nie, aber in einem Fall der Service-Bindung ist es doppelt schlechter) – snuk182

+2

-1, der Dev-Guide ist falsch. 'bindService()' gibt einen Wert zurück. Von http://developer.android.com/reference/android/content/Context.html, "wenn Sie erfolgreich an den Dienst gebunden haben, wird True zurückgegeben; false wird zurückgegeben, wenn die Verbindung nicht hergestellt wird, so dass Sie die Serviceobjekt. " –

Verwandte Themen