2012-05-29 10 views
7

Sto cercando di legare il servizio da un altro servizio come questo:Quando verrà chiamato esattamente onServiceConnected per il servizio limitato?

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; 
     } 
    }  
} 

Questo è un semplice frammento di che ho preso da campioni di Goolge :) Il codice funziona bene e mDataService contiene un riferimento a un'istanza ServiceB, ma c'è una cosa che non riuscivo a capire: il callback onServiceConnected viene chiamato dopo la chiamata a onStart. Come ho visto sui documenti di Android, the callback is running on the main thread - ma posso contare sul fatto che accadrà SEMPRE in questo ordine nel mio caso? onCreate -> onStart -> onServiceConnected?

risposta

2

Non ci farei affidamento. Dipende se ServiceA e ServiceB sono in esecuzione nello stesso o in processi diversi. Probabilmente dipende anche se ServiceB è già stato avviato. Dovresti scrivere il tuo codice in modo da non dipendere da questa sequenza di eventi.

12

Non è stato chiaramente affermato nella guida ufficiale dev, il Context.bindService() è davvero una chiamata asincrona, questo spiega anche il motivo per cui ServiceConnection.onServiceConnected() è implementato come un callback. Controlla il dev guide:

Un client può collegarsi al servizio chiamando bindService(). Quando lo fa, deve fornire un'implementazione di ServiceConnection, che monitora la connessione con il servizio. Il metodo bindService() restituisce immediatamente senza un valore, ma quando il sistema Android crea la connessione tra il client e il servizio, chiama onServiceConnected() sul ServiceConnection, per consegnare l'IBinder che il client può utilizzare per comunicare con il servizio.

ServiceConnection.onServiceConnected() viene chiamato su thread dell'interfaccia utente ad un certo punto nel futuro (non subito dopo la chiamata Context.bindService()), una volta che il collegamento al servizio sia correttamente stabilita.

+0

Sì. E il seguente dovrebbe essere indicato con grandi lettere rosse da qualche parte: ** Non bloccare il thread di attività/service starter in attesa di una connessione di servizio! ** (beh, non bloccarlo mai, ma in caso di service binding è doppio peggiore) – snuk182

+2

-1, la guida dev è errata. 'bindService()' restituisce un valore. Da http://developer.android.com/reference/android/content/Context.html, "se ci si è associati correttamente al servizio, viene restituito true, viene restituito false se la connessione non viene effettuata in modo da non ricevere oggetto di servizio. " –

Problemi correlati