Un servizio associato è il server in un'interfaccia client-server. Consente ai componenti come attività associate al servizio, inviare richieste, ricevere risposte ed eseguire comunicazione tra processi (IPC, Inter-Process Communication). In genere un servizio associato rimane attivo solo mentre ne serve un altro dell'applicazione e non viene eseguita in background a tempo indeterminato.
Questo documento descrive come creare un servizio associato, incluse le modalità di associazione al servizio da altri componenti dell'applicazione. Per ulteriori informazioni sui servizi in ad esempio come recapitare notifiche da un servizio e impostare il servizio per l'esecuzione in primo piano, fai riferimento ai Panoramica dei servizi.
Nozioni di base
Un servizio associato è un'implementazione della classe Service
che consente
che altre applicazioni si collegano e
interagiscono con quest'ultimo. Per specificare l'associazione per un
implementi il metodo di callback onBind()
. Questo
restituisce un oggetto IBinder
che definisce l'interfaccia di programmazione che
che i client possono usare per interagire con il servizio.
Associazione a un servizio avviato
Come spiegato nella Panoramica dei servizi,
puoi creare un servizio avviato e associato. Vale a dire che puoi avviare
di servizio chiamando startService()
, che consente
viene eseguito a tempo indeterminato. Puoi anche consentire a un client di associarsi al servizio
chiamata bindService()
.
Se consenti l'avvio e l'associazione del servizio, all'avvio del servizio
Il sistema non elimina il servizio quando tutti i client vengono slegati.
Devi invece
interrompere esplicitamente il servizio chiamando stopSelf()
o stopService()
.
Anche se di solito implementi onBind()
o onStartCommand()
, a volte capita
necessario per
implementarle entrambe. Ad esempio, per un music player potrebbe essere utile consentire l'esecuzione del suo servizio
a tempo indeterminato e come vincolanti. In questo modo, un'attività può avviare il servizio per riprodurre
che continuerà a essere riprodotta anche se l'utente esce dall'applicazione. Quindi, quando l'utente
all'applicazione, l'attività può associarsi al servizio per riprendere il controllo
per riprodurre un video.
Per saperne di più sul ciclo di vita dei servizi quando aggiungi l'associazione a un servizio avviato, consulta la sezione Gestire il ciclo di vita di un servizio associato.
Un client si collega a un servizio chiamando
bindService()
. Quando succede, deve
fornire un'implementazione di ServiceConnection
, che
monitora la connessione al servizio. Il valore restituito
bindService()
indica se le proprietà
servizio richiesto e se il client è autorizzato ad accedervi.
Quando
il sistema Android crea la connessione tra il client e il servizio,
chiama onServiceConnected()
il giorno ServiceConnection
. La
Il metodo onServiceConnected()
include un IBinder
, che il client utilizzerà per comunicare con il servizio associato.
Puoi collegare più client a un servizio contemporaneamente. Tuttavia,
di sistema memorizza nella cache il canale di comunicazione del servizio IBinder
.
In altre parole, il sistema chiama l'elemento onBind()
del servizio
per generare IBinder
solo quando il primo
vincoli client. Il sistema invia quindi lo stesso IBinder
a tutti i client aggiuntivi che si associano allo stesso servizio, senza chiamare
onBind()
di nuovo.
Quando l'ultimo client si scollega dal servizio, il sistema elimina il servizio, a meno che il parametro
è stato avviato utilizzando startService()
.
La parte più importante dell'implementazione del servizio associato è la definizione dell'interfaccia
restituito dal metodo di callback onBind()
. Le seguenti
illustra i diversi modi in cui è possibile definire
interfaccia di IBinder
.
Crea un servizio associato
Quando crei un servizio che fornisce l'associazione, devi fornire un valore IBinder
che fornisce l'interfaccia di programmazione che i client possono utilizzare per interagire con il servizio. Là
puoi definire l'interfaccia in tre modi:
- Ampliare la classe Binder
- Se il servizio è privato per la tua applicazione e viene eseguito nello stesso processo
come client, cosa comune, per creare la tua interfaccia estendendo
Binder
classe e la restituzione di un'istanzaonBind()
. Il cliente riceve iBinder
e puoi usarlo per accedere direttamente ai metodi pubblici disponibili inBinder
implementazione oService
.Questa è la tecnica preferita quando il tuo servizio è semplicemente un worker in background per il tuo un'applicazione. L'unico caso d'uso quando questo non è il modo migliore per creare l'interfaccia è se il servizio è utilizzato da altre applicazioni o in processi separati.
- Utilizzare un Messenger
- Se hai bisogno che la tua interfaccia funzioni su diversi processi, puoi creare
un'interfaccia per il servizio con un
Messenger
. In questo modo, il servizio definisce unHandler
che risponde a diversi tipi di oggettiMessage
.Questo
Handler
è la base per unMessenger
che può quindi condividere unIBinder
con il client, consentendo al client di inviare comandi al servizio utilizzando oggettiMessage
. Inoltre, il cliente può definire un valoreMessenger
per far sì che il servizio possa inviare messaggi.Questo è il modo più semplice per eseguire la comunicazione tra processi (IPC), perché
Messenger
mette in coda tutte le richieste in un singolo thread in modo che non sia necessario progettare il tuo servizio sia sicuro per i thread. - Usa il modello AIDL
- Android Interface Definition Language (AIDL) scompone gli oggetti in
che il sistema operativo è in grado di comprendere e le esegue il marshall tra i processi per l'esecuzione
IPC. La tecnica precedente, utilizzando un
Messenger
, si basa in realtà sull'AIDL come la sua struttura sottostante.Come accennato nella sezione precedente,
Messenger
crea una coda di tutte le richieste del client in un singolo thread, quindi il servizio riceve le richieste una alla volta. Se Se però vuoi che il servizio gestisca più richieste contemporaneamente, puoi usare AIDL strato Add. In questo caso, il servizio deve essere sicuro per i thread e in grado di eseguire il multi-threading.Per usare direttamente l'AIDL, crea un file
.aidl
che definisce l'interfaccia di programmazione. Gli strumenti SDK per Android utilizzano questo file per generare una classe astratta che implementa l'interfaccia e gestisce l'IPC, può quindi estendersi all'interno del tuo servizio.
Nota: per la maggior parte delle applicazioni, AIDL non è la scelta migliore per creare un servizio associato, perché potrebbe richiedere funzionalità di multi-threading può comportare un'implementazione più complicata. Pertanto, il presente documento non tratta di come per utilizzarlo per il tuo servizio. Se hai la certezza di aver bisogno per utilizzare direttamente l'AIDL, consulta l'articolo AIDL documento.
Estendi la classe Binder
Se solo l'applicazione locale utilizza il tuo servizio e non è necessario
lavorare tra i vari processi,
puoi implementare la tua classe Binder
che fornisce al cliente
ai metodi pubblici nel servizio.
Nota: questo funziona solo se il client e il servizio sono nello stesso servizio un'applicazione e un processo, che è il più comune. Ad esempio, questa soluzione funziona bene per un che deve associare al proprio servizio un'attività che riproduce musica nel sfondo.
Ecco come impostarlo:
- Nel tuo servizio, crea un'istanza di
Binder
che uno dei seguenti:- Contiene metodi pubblici che il client può chiamare.
- Restituisce l'istanza
Service
corrente, che dispone di metodi pubblici che il cliente può chiamare. - Restituisce un'istanza di un'altra classe ospitata dal servizio con metodi pubblici che che il cliente può chiamare.
- Restituisci questa istanza di
Binder
dal metodo di callbackonBind()
. - Nel client, ricevi
Binder
dal metodo di callbackonServiceConnected()
e effettuare chiamate al servizio associato utilizzando i metodi forniti.
Nota: il servizio e il client devono essere nello stesso account in modo che il client possa trasmettere l'oggetto restituito e chiamare correttamente le relative API. Il servizio e il client devono essere nello stesso processo, perché questa tecnica non esegue alcuna il marshalling tra i processi.
Ad esempio, ecco un servizio che fornisce ai clienti accesso ai metodi nel servizio tramite
un'implementazione Binder
:
Kotlin
class LocalService : Service() { // Binder given to clients. private val binder = LocalBinder() // Random number generator. private val mGenerator = Random() /** Method for clients. */ val randomNumber: Int get() = mGenerator.nextInt(100) /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ inner class LocalBinder : Binder() { // Return this instance of LocalService so clients can call public methods. fun getService(): LocalService = this@LocalService } override fun onBind(intent: Intent): IBinder { return binder } }
Java
public class LocalService extends Service { // Binder given to clients. private final IBinder binder = new LocalBinder(); // Random number generator. private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public methods. return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return binder; } /** Method for clients. */ public int getRandomNumber() { return mGenerator.nextInt(100); } }
LocalBinder
fornisce il metodo getService()
per consentire ai clienti di recuperare i
l'istanza attuale di LocalService
. In questo modo i client possono chiamare metodi pubblici
completamente gestito di Google Cloud. Ad esempio, i clienti possono chiamare getRandomNumber()
dal servizio.
Ecco un'attività che si collega a LocalService
e chiama getRandomNumber()
Quando un utente fa clic su un pulsante:
Kotlin
class BindingActivity : Activity() { private lateinit var mService: LocalService private var mBound: Boolean = false /** Defines callbacks for service binding, passed to bindService(). */ private val connection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { // We've bound to LocalService, cast the IBinder and get LocalService instance. val binder = service as LocalService.LocalBinder mService = binder.getService() mBound = true } override fun onServiceDisconnected(arg0: ComponentName) { mBound = false } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) } override fun onStart() { super.onStart() // Bind to LocalService. Intent(this, LocalService::class.java).also { intent -> bindService(intent, connection, Context.BIND_AUTO_CREATE) } } override fun onStop() { super.onStop() unbindService(connection) mBound = false } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute). */ fun onButtonClick(v: View) { if (mBound) { // Call a method from the LocalService. // However, if this call is something that might hang, then put this request // in a separate thread to avoid slowing down the activity performance. val num: Int = mService.randomNumber Toast.makeText(this, "number: $num", Toast.LENGTH_SHORT).show() } } }
Java
public class BindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to LocalService. Intent intent = new Intent(this, LocalService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); unbindService(connection); mBound = false; } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute). */ public void onButtonClick(View v) { if (mBound) { // Call a method from the LocalService. // However, if this call is something that might hang, then put this request // in a separate thread to avoid slowing down the activity performance. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** Defines callbacks for service binding, passed to bindService(). */ private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance. LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }
L'esempio precedente mostra in che modo il client si associa al servizio utilizzando un'implementazione
ServiceConnection
e il callback onServiceConnected()
. Il prossimo
fornisce ulteriori informazioni su questo processo di associazione al servizio.
Nota: nell'esempio precedente,
onStop()
slega il client dal servizio.
Svincola i clienti dai servizi nei momenti opportuni, come illustrato nelle
Note aggiuntive.
Per altro codice di esempio, consulta
LocalService.java
e
LocalServiceActivities.java
in ApiDemos.
Utilizzare un Messenger
Se hai bisogno che il tuo servizio comunichi con i processi remoti, puoi utilizzare un
Messenger
per fornire l'interfaccia per il tuo servizio. Questa tecnica consente
esegui la comunicazione inter-process (IPC) senza dover usare AIDL.
L'utilizzo di un Messenger
per l'interfaccia
più semplice rispetto all'utilizzo di AIDL perché Messenger
mette in coda
tutte le chiamate al servizio. Un'interfaccia AIDL pura invia richieste simultanee al
che deve quindi gestire il multithreading.
Per la maggior parte delle applicazioni, il servizio non richiede il multi-threading, quindi l'utilizzo di un'Messenger
consente al servizio di gestire una chiamata alla volta. Se è importante
in modo che il tuo servizio sia multithread, usa AIDL per definire l'interfaccia.
Ecco un riepilogo di come utilizzare un Messenger
:
- Il servizio implementa un
Handler
che riceve un callback per ogni una chiamata da un cliente. - Il servizio utilizza
Handler
per creare unMessenger
oggetto (che è un riferimento aHandler
). Messenger
crea unIBinder
che il servizio i resi ai clienti daonBind()
.- I client utilizzano
IBinder
per creare un'istanza diMessenger
(che fa riferimento alHandler
del servizio), che il client utilizza per inviareMessage
oggetti al servizio. - Il servizio riceve ogni
Message
nel suoHandler
, in particolare nel metodohandleMessage()
.
In questo modo, il client non avrà metodi per chiamare il servizio. Invece,
Il client recapita i messaggi (Message
oggetti) che il servizio
riceve in
è Handler
.
Ecco un semplice servizio di esempio che utilizza un'interfaccia Messenger
:
Kotlin
/** Command to the service to display a message. */ private const val MSG_SAY_HELLO = 1 class MessengerService : Service() { /** * Target we publish for clients to send messages to IncomingHandler. */ private lateinit var mMessenger: Messenger /** * Handler of incoming messages from clients. */ internal class IncomingHandler( context: Context, private val applicationContext: Context = context.applicationContext ) : Handler() { override fun handleMessage(msg: Message) { when (msg.what) { MSG_SAY_HELLO -> Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show() else -> super.handleMessage(msg) } } } /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ override fun onBind(intent: Intent): IBinder? { Toast.makeText(applicationContext, "binding", Toast.LENGTH_SHORT).show() mMessenger = Messenger(IncomingHandler(this)) return mMessenger.binder } }
Java
public class MessengerService extends Service { /** * Command to the service to display a message. */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ static class IncomingHandler extends Handler { private Context applicationContext; IncomingHandler(Context context) { applicationContext = context.getApplicationContext(); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } /** * Target we publish for clients to send messages to IncomingHandler. */ Messenger mMessenger; /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); mMessenger = new Messenger(new IncomingHandler(this)); return mMessenger.getBinder(); } }
Il metodo handleMessage()
nel
Handler
è il luogo in cui il servizio riceve il Message
in arrivo
e decide cosa fare, in base al membro what
.
Tutto ciò che un client deve fare è creare un Messenger
basato su IBinder
restituito dal servizio e inviare un messaggio utilizzando send()
. Ad esempio, di seguito è riportata un'attività che collega
e consegna il messaggio MSG_SAY_HELLO
al servizio:
Kotlin
class ActivityMessenger : Activity() { /** Messenger for communicating with the service. */ private var mService: Messenger? = null /** Flag indicating whether we have called bind on the service. */ private var bound: Boolean = false /** * Class for interacting with the main interface of the service. */ private val mConnection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = Messenger(service) bound = true } override fun onServiceDisconnected(className: ComponentName) { // This is called when the connection with the service has been // unexpectedly disconnected—that is, its process crashed. mService = null bound = false } } fun sayHello(v: View) { if (!bound) return // Create and send a message to the service, using a supported 'what' value. val msg: Message = Message.obtain(null, MSG_SAY_HELLO, 0, 0) try { mService?.send(msg) } catch (e: RemoteException) { e.printStackTrace() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) } override fun onStart() { super.onStart() // Bind to the service. Intent(this, MessengerService::class.java).also { intent -> bindService(intent, mConnection, Context.BIND_AUTO_CREATE) } } override fun onStop() { super.onStop() // Unbind from the service. if (bound) { unbindService(mConnection) bound = false } } }
Java
public class ActivityMessenger extends Activity { /** Messenger for communicating with the service. */ Messenger mService = null; /** Flag indicating whether we have called bind on the service. */ boolean bound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = new Messenger(service); bound = true; } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected—that is, its process crashed. mService = null; bound = false; } }; public void sayHello(View v) { if (!bound) return; // Create and send a message to the service, using a supported 'what' value. Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to the service. bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service. if (bound) { unbindService(mConnection); bound = false; } } }
Questo esempio non mostra come il servizio può rispondere al client.
Se desideri
servizio per rispondere, devi anche creare un Messenger
nel client.
Quando il client riceve il callback onServiceConnected()
, invia un Message
al servizio che include
Messenger
del cliente nel parametro replyTo
del metodo send()
.
È possibile vedere un esempio di come offrire messaggi bidirezionali in
MessengerService.java
(servizio) e
Esempi di MessengerServiceActivities.java
(client).
Associazione a un servizio
I componenti dell'applicazione (client) possono essere associati a un servizio chiamando
bindService()
. Android
quindi chiama il metodo onBind()
del servizio, che restituisce un IBinder
per l'interazione con
il servizio.
L'associazione è asincrona e bindService()
restituisce immediatamente senza restituire IBinder
in
il cliente. Per ricevere IBinder
, il cliente deve creare un
di ServiceConnection
e la passiamo a bindService()
. ServiceConnection
include un metodo di callback che
chiamate di sistema per l'invio del IBinder
.
Nota: solo le attività, i servizi e i fornitori di contenuti possono vincolare a un servizio: non puoi eseguire l'associazione a un servizio da un broadcast receiver.
Per eseguire l'associazione a un servizio dal tuo client, segui questi passaggi:
- Implementa
ServiceConnection
.L'implementazione deve sostituire due metodi di callback:
onServiceConnected()
- Il sistema la chiama per consegnare il valore
IBinder
restituito da il metodoonBind()
del servizio. onServiceDisconnected()
- Il sistema Android lo chiama quando la connessione al servizio è inaspettata persi, ad esempio quando il servizio ha un arresto anomalo o si interrompe. Non chiamato quando slega il client.
- Chiama
bindService()
, superando l'implementazione diServiceConnection
.Nota: se il metodo restituisce false, il valore non dispone di una connessione valida al servizio. Invece, chiama
unbindService()
nel tuo client. In caso contrario, il client mantiene il servizio quando è inattivo. - Quando il sistema chiama il metodo di callback
onServiceConnected()
, puoi iniziare a effettuare chiamate al servizio, utilizzando i metodi definiti dall'interfaccia. - Per disconnetterti dal servizio, chiama
unbindService()
.Se il client è ancora associato a un servizio quando l'app lo elimina, determina lo slegamento del client. È consigliabile svincolare il cliente non appena viene eseguito a interagire con il servizio. Ciò consente di arrestare il servizio inattivo. Per ulteriori informazioni sulle tempistiche appropriate per vincolare e svincolare, consulta la sezione Note aggiuntive.
L'esempio seguente collega il client al servizio creato in precedenza
estendere la classe Binder, quindi deve solo trasmettere il testo restituito
IBinder
alla classe LocalBinder
e richiedi l'istanza LocalService
:
Kotlin
var mService: LocalService val mConnection = object : ServiceConnection { // Called when the connection with the service is established. override fun onServiceConnected(className: ComponentName, service: IBinder) { // Because we have bound to an explicit // service that is running in our own process, we can // cast its IBinder to a concrete class and directly access it. val binder = service as LocalService.LocalBinder mService = binder.getService() mBound = true } // Called when the connection with the service disconnects unexpectedly. override fun onServiceDisconnected(className: ComponentName) { Log.e(TAG, "onServiceDisconnected") mBound = false } }
Java
LocalService mService; private ServiceConnection mConnection = new ServiceConnection() { // Called when the connection with the service is established. public void onServiceConnected(ComponentName className, IBinder service) { // Because we have bound to an explicit // service that is running in our own process, we can // cast its IBinder to a concrete class and directly access it. LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } // Called when the connection with the service disconnects unexpectedly. public void onServiceDisconnected(ComponentName className) { Log.e(TAG, "onServiceDisconnected"); mBound = false; } };
Con questo ServiceConnection
, il client può eseguire l'associazione a un servizio
passando
a bindService()
, come mostrato nell'esempio seguente:
Kotlin
Intent(this, LocalService::class.java).also { intent -> bindService(intent, connection, Context.BIND_AUTO_CREATE) }
Java
Intent intent = new Intent(this, LocalService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE);
- Il primo parametro di
bindService()
è unIntent
che nomina esplicitamente il servizio da associare.Attenzione:se utilizzi un intent per l'associazione a una
Service
, assicurati che la tua app sia sicura con un messaggio esplicita l'intento. L'utilizzo di un intent implicito per avviare un servizio è un rischio per la sicurezza perché non puoi sapere con certezza quale servizio risponda all'intento, e l'utente non può vedere quale servizio viene avviato. A partire da Android 5.0 (livello API 21), il sistema genera un'eccezione se chiamibindService()
con un intento implicito. - Il secondo parametro è l'oggetto
ServiceConnection
. - Il terzo parametro è un flag che indica le opzioni per l'associazione, di solito
BIND_AUTO_CREATE
, per creare il servizio, se non lo è già vivo. Gli altri valori possibili sonoBIND_DEBUG_UNBIND
,BIND_NOT_FOREGROUND
o0
per nessuno.
Note aggiuntive
Di seguito sono riportate alcune note importanti sull'associazione a un servizio:
- Trappola sempre
DeadObjectException
eccezioni, che vengono generate quando si interrompe la connessione. Questa è l'unica eccezione generata dai metodi remoti. - Gli oggetti vengono conteggiati nei processi.
- In genere accoppi l'associazione e lo slegamento durante
Abbinando i momenti di lancio e rimozione del ciclo di vita del cliente, come descritto nei
i seguenti esempi:
- Se devi interagire con il servizio solo quando la tua attività è visibile, esegui l'associazione durante
onStart()
e slegala duranteonStop()
. - Se vuoi che la tua attività riceva risposte anche quando è interrotta nella
sfondo, eseguire l'associazione durante
onCreate()
e slegare duranteonDestroy()
. Ricorda che ciò implica che l'attività deve utilizzare il servizio per tutta la durata dell'esecuzione, anche in background; pertanto, quando se il servizio si trova in un altro processo, ne aumenti il peso di essere terminati dal sistema.
Nota: di solito non vincoli e svincoli durante le richiamate
onResume()
eonPause()
dell'attività, perché questi callback vengono eseguiti ogni durante la transizione del ciclo di vita. Mantieni al minimo l'elaborazione che si verifica in queste transizioni.Inoltre, se più attività nella tua applicazione sono associate allo stesso servizio ed è presente transizione tra due di queste attività, il servizio potrebbe essere eliminato e ricreato come attività slega (durante la pausa) prima di quella successiva vincolata (durante la ripresa). Questa attività passa per come e varie attività coordinano i loro cicli di vita è descritto in Il ciclo di vita dell'attività.
- Se devi interagire con il servizio solo quando la tua attività è visibile, esegui l'associazione durante
Per altro codice campione che mostra come eseguire l'associazione a un servizio, consulta
Classe RemoteService.java
in ApiDemos.
Gestire il ciclo di vita di un servizio associato
Quando un servizio viene slegato da tutti i client, il sistema Android lo elimina.
(a meno che non sia stato iniziato a utilizzare
startService()
).
Non devi quindi gestire il ciclo di vita del tuo servizio
un servizio puramente vincolato. Il sistema Android le gestisce per te in base
se è associato a qualche client.
Tuttavia, se scegli di implementare il metodo di callback onStartCommand()
, devi interrompere esplicitamente il servizio perché
è ora considerato avviato. In questo caso, il servizio viene eseguito fino a quando
si arresta con stopSelf()
o un altro componente chiama stopService()
, a prescindere dal fatto che sia associato a qualche
clienti.
Inoltre, se il servizio viene avviato e accetta l'associazione, quando il sistema chiama
il tuo metodo onUnbind()
, se vuoi puoi restituire
true
se vuoi ricevere una chiamata a onRebind()
la prossima volta che un client si associa al servizio. onRebind()
restituisce void, ma il client riceve comunque IBinder
nella sua
Chiamata onServiceConnected()
.
La figura seguente illustra la logica di questo tipo di ciclo di vita.
Per saperne di più sul ciclo di vita di un servizio avviato, consulta la Panoramica dei servizi.