Un servicio vinculado es el servidor de una interfaz cliente-servidor. Permite que los componentes como las actividades que se vinculan con el servicio, envían solicitudes, reciben respuestas y realizan comunicación entre procesos (IPC). Un servicio vinculado, por lo general, solo está activo mientras le presta servicio a otro componente de la aplicación y no se ejecuta en segundo plano indefinidamente.
En este documento, se describe cómo crear un servicio vinculado, además de cómo establecer una vinculación con el servicio desde otros componentes de la aplicación. Para obtener información adicional sobre los servicios en generales, por ejemplo, cómo enviar notificaciones desde un servicio y configurar el servicio para que se ejecute en primer plano, consulta la Descripción general de los servicios.
Conceptos básicos
Un servicio vinculado es una implementación de la clase Service
que permite
otras aplicaciones se vinculan e interactúan con él. Para vincular un objeto
implementa el método de devolución de llamada onBind()
. Este método muestra un objeto IBinder
que define la interfaz de programación que los clientes pueden usar para interactuar con el servicio.
Vincular a un servicio iniciado
Como se explica en la Descripción general de los servicios,
puede crear un servicio
iniciado y vinculado. Es decir, puedes empezar un
de servicio llamando a startService()
, que le permite a la
que el servicio se ejecute indefinidamente. También puedes permitir que un cliente se vincule con el servicio
llamando a bindService()
.
Si permites que tu servicio se inicie y se vincule, entonces, cuando se inicie,
el sistema no destruye el servicio cuando se desvinculan todos los clientes.
En su lugar, debes detener explícitamente el servicio llamando a stopSelf()
o stopService()
.
Si bien generalmente implementas onBind()
o onStartCommand()
, a veces es necesario implementar ambos. Por ejemplo, a un reproductor de música podría resultarle útil dejar que su servicio se ejecute
de forma indefinida y también proporcionan vinculación. De esta manera, una actividad puede iniciar el servicio para que reproduzca algunas
música y esta sigue reproduciéndose incluso si el usuario sale de la aplicación. Cuando el usuario regrese a la aplicación, la actividad podrá vincularse al servicio para volver a tener el control de la reproducción.
Para obtener más información sobre el ciclo de vida del servicio cuando se agrega la vinculación a un servicio iniciado, consulta la sección Cómo administrar el ciclo de vida de un servicio vinculado.
Un cliente se vincula a un servicio llamando a bindService()
. Cuando lo hace, debe implementar ServiceConnection
, que supervisa la conexión con el servicio. El valor que se muestra de bindService()
indica si el servicio solicitado existe y si se le permite al cliente acceder a él.
Cuándo
el sistema Android crea la conexión entre el cliente y el servicio,
llama al onServiceConnected()
en el ServiceConnection
. El
El método onServiceConnected()
incluye un IBinder
.
que el cliente usa para comunicarse con el servicio vinculado.
Puedes conectar varios clientes a un servicio simultáneamente. Sin embargo, el sistema almacena en caché el canal de comunicación del servicio IBinder
.
En otras palabras, el sistema llama a la onBind()
del servicio
para generar el IBinder
solo cuando el primer
vinculaciones del cliente. El sistema entonces entrega el mismo IBinder
a todos los clientes adicionales que se vinculan a ese mismo servicio, sin volver a llamar a onBind()
.
Cuando el último cliente se desvincula del servicio, el sistema destruye el servicio, a menos que el
servicio se inició con startService()
.
La parte más importante de la implementación de tu servicio vinculado es definir la interfaz que mostrará tu método de devolución de llamada onBind()
. Lo siguiente
en la que se explican varias formas en las que puedes definir la configuración
IBinder
.
Crea un servicio vinculado
Al crear un servicio que proporciona la capacidad de crear una vinculación, debes proporcionar un IBinder
que contenga la interfaz de programación que los clientes pueden usar para interactuar con el servicio. Puedes definir la interfaz de las siguientes tres maneras:
- Cómo extender la clase Binder
- Si tu servicio es privado para tu propia aplicación y se ejecuta en el mismo proceso
como cliente, lo cual es común, crea tu interfaz extendiendo el
Binder
clase y mostrar una instancia de esta desdeonBind()
El cliente recibe elBinder
y puede usarlo para acceder directamente a métodos públicos disponibles en la implementación deBinder
oService
.Esta es la técnica preferida cuando tu servicio es solo un trabajador en segundo plano de tu propia aplicación. El único caso de uso en el que esta no es la forma preferida de crear tu interfaz es si otras aplicaciones usan el servicio o en procesos independientes.
- Cómo usar Messenger
- Si necesitas que tu interfaz funcione en diferentes procesos, puedes crear una para el servicio con un
Messenger
. De esta manera, el servicio define unHandler
que responde a diferentes tipos de objetosMessage
.Este/a
Handler
es la base para unMessenger
que luego puede compartir unIBinder
con el cliente, lo que le permite enviar comandos al servicio con objetosMessage
. Además, el cliente puede definir unMessenger
de por su cuenta, de modo que el servicio pueda devolver mensajes.Esta es la manera más sencilla de establecer comunicación entre procesos (IPC), ya que
Messenger
pone en cola todas las solicitudes en un solo subproceso a fin de que no debas diseñar tu servicio de modo que sea seguro para subprocesos. - Cómo usar el AIDL
- El Lenguaje de definición de la interfaz de Android (AIDL) descompone los objetos en
primitivas que el sistema operativo puede comprender y las ordena entre procesos para realizar
que se encuentra en la IPC. La técnica anterior, que utiliza un
Messenger
, usa AIDL como estructura subyacente.Como se mencionó en la sección anterior,
Messenger
crea una cola de todas las solicitudes del cliente en un solo subproceso, de modo que el servicio reciba las solicitudes de a una. Sin embargo, si quieres que tu servicio administre varias solicitudes de forma simultánea, puedes usar AIDL directamente. En este caso, tu servicio debe ser seguro para subprocesos y capaz de ejecutar varios subprocesos.Para usar el AIDL directamente, Crea un archivo
.aidl
que defina la interfaz de programación. Las herramientas del SDK de Android usan ese archivo para generar una clase abstracta que implemente la interfaz y manipule la IPC, que luego podrás extender en tu servicio.
Nota: En la mayoría de las aplicaciones, el AIDL no es la mejor opción para crear un servicio de enlace, ya que podría requerir capacidades de multiprocesamiento y puede dar como resultado una implementación más complicada. Por lo tanto, en este documento no se analiza para usarla en tu servicio. Si estás seguro de que necesitas Para usar el AIDL de forma directa, consulta el AIDL .
Cómo extender la clase Binder
Si solo la aplicación local usa tu servicio y no necesita hacerlo
trabajar en todos los procesos,
puedes implementar tu propia clase Binder
que le proporcione a tu cliente un
acceso a métodos públicos en el servicio.
Nota: Esto funciona únicamente si el cliente y el servicio se encuentran en la misma aplicación y el mismo proceso, que es lo más común. Por ejemplo, esto funciona bien para un que necesita enlazar una actividad con su propio servicio que reproduce música en la en segundo plano.
A continuación, te indicamos cómo configurarlo:
- En tu servicio, crea una instancia de
Binder
que haga lo siguiente:- Contenga métodos públicos que el cliente pueda llamar
- Muestre la instancia
Service
actual, que tiene métodos públicos que el cliente puede llamar - Muestre una instancia de otra clase alojada por el servicio con métodos públicos que el cliente pueda llamar
- Muestre esta instancia
Binder
desde el método de devolución de llamadaonBind()
- En el cliente, reciba
Binder
del método de devolución de llamadaonServiceConnected()
y realice llamadas al servicio vinculado usando los métodos proporcionados
Nota: El servicio y el cliente deben estar en la misma aplicación para que el cliente pueda convertir el objeto mostrado y llamar a sus API de forma correcta. El servicio y cliente también deben estar en el mismo proceso, ya que esta técnica no realiza ningún el ordenamiento entre procesos.
Por ejemplo, aquí hay un servicio que les brinda a los clientes acceso a métodos del servicio a través de la implementación de un 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
proporciona el método getService()
para que los clientes obtengan la instancia actual de LocalService
. Esto permite a los clientes llamar a métodos públicos en la
servicio. Por ejemplo, los clientes pueden llamar a getRandomNumber()
desde el servicio.
A continuación, se proporciona una actividad que se vincula a LocalService
y llama a getRandomNumber()
cuando se hace clic en un botón:
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; } }; }
En el ejemplo anterior, se muestra cómo el cliente se vincula con el servicio a través de una implementación de
ServiceConnection
y la devolución de llamada onServiceConnected()
. En la siguiente sección, se proporciona más información sobrde este proceso de vinculación con el servicio.
Nota: En el ejemplo anterior, la
El método onStop()
desvincula al cliente del servicio.
Desvincular a los clientes de los servicios en los momentos adecuados, como se explica en el
Notas adicionales.
Para acceder a otros ejemplos de código, consulta las clases LocalService.java
y LocalServiceActivities.java
en ApiDemos.
Cómo usar un objeto Messenger
Si necesitas que tu servicio se comunique con procesos remotos, puedes usar un Messenger
a fin de proporcionar la interfaz para tu servicio. Esta técnica permite
Estableces comunicación entre procesos (IPC) sin necesidad de usar AIDL.
El uso de un Messenger
para tu interfaz es más sencillo que el uso de AIDL, ya que Messenger
pone en cola todas las llamadas al servicio. Una interfaz de AIDL pura envía solicitudes simultáneas al
que debe controlar el multiprocesamiento.
Para la mayoría de las aplicaciones, el servicio no necesita ejecutar varios subprocesos, por lo que el uso de un Messenger
permite que el servicio maneje una llamada a la vez. Si es importante
que tu servicio ejecute varios subprocesos, usa AIDL para definir tu interfaz.
Aquí te mostramos un resumen de cómo usar un Messenger
:
- El servicio implementa un
Handler
que recibe una devolución por cada llamada de un cliente. - El servicio usa el
Handler
para crear un objetoMessenger
(que es una referencia alHandler
). - El
Messenger
crea unIBinder
que el servicio muestra a los clientes desdeonBind()
. - Los clientes usan el
IBinder
para crear instancias delMessenger
(que hace referencia alHandler
del servicio), que el cliente usa para enviar objetosMessage
al servicio. - El servicio recibe cada
Message
en suHandler
; específicamente, en el métodohandleMessage()
.
De esta manera, no hay métodos que el cliente pueda usar para llamar al servicio. En su lugar, el cliente envía mensajes (objetos Message
) que el servicio recibe en su Handler
.
Aquí te mostramos un ejemplo sencillo de servicio que usa una interfaz 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(); } }
El método handleMessage()
en la
Handler
es donde el servicio recibe el Message
entrante.
y decide qué hacer, según el miembro what
.
Todo lo que el cliente debe hacer es crear un Messenger
en función del IBinder
que muestra el servicio y enviar un mensaje con send()
. Por ejemplo, esta es una actividad que se vincula al
y entrega el mensaje MSG_SAY_HELLO
al servicio:
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; } } }
En este ejemplo, no se muestra cómo el servicio puede responder al cliente.
Si quieres que el servicio responda, también deberás crear un Messenger
en el cliente.
Cuando el cliente recibe la devolución de llamada onServiceConnected()
, envía un Message
al servicio que incluye el Messenger
del cliente en el parámetro replyTo
del método send()
.
Puedes ver la manera de proporcionar un sistema de mensajería bidireccional en los ejemplos de MessengerService.java
(servicio) y MessengerServiceActivities.java
(cliente).
Vincular a un servicio
Los componentes de la aplicación (clientes) pueden establecer una vinculación con un servicio llamando a bindService()
. Luego, el sistema Android llama al método onBind()
del servicio, que muestra un IBinder
para interactuar con él.
La vinculación es asíncrona, y bindService()
se muestra inmediatamente sin mostrarle el IBinder
al cliente. Para recibir el IBinder
, el cliente debe crear una instancia de ServiceConnection
y pasarla a bindService()
. ServiceConnection
incluye un método de devolución de llamada al que el sistema llama para enviar el IBinder
.
Nota: Solo las actividades, los servicios y los proveedores de contenido pueden establecer vinculaciones con un servicio; no puedes establecer vinculaciones con un servicio desde un receptor de emisión.
Para establecer una vinculación con un servicio desde tu cliente, debes hacer lo siguiente:
- Implementa
ServiceConnection
.Tu implementación debe anular dos métodos de devolución de llamada:
onServiceConnected()
- El sistema lo llama para enviar el
IBinder
que muestra el métodoonBind()
del servicio. onServiceDisconnected()
- El sistema Android lo llama cuando la conexión al servicio es inesperada se pierden, como cuando el servicio falla o se desactiva. No lo llama cuando se desvincula el cliente.
- Llama a
bindService()
y pasa la implementación deServiceConnection
.Nota: Si el método muestra un valor falso, significa que tu cliente no tiene una conexión válida con el servicio. Sin embargo, llama
unbindService()
en tu cliente. De lo contrario, el cliente impedirá que se ejecute se apaga cuando está inactivo. - Cuando el sistema llama a tu método de devolución de llamada
onServiceConnected()
, puedes comenzar a realizar llamadas al servicio usando los métodos definidos por la interfaz. - Para desconectarte del servicio, llama a
unbindService()
.Si tu cliente aún está vinculado a un servicio cuando tu app destruye el cliente, la destrucción hace que se desvincule el cliente. Una práctica recomendada es desvincular al cliente tan pronto como se hace. de interactuar con el servicio. Esto permite que se cierre el servicio inactivo. Más información sobre momentos apropiados para la vinculación y la desvinculación, consulta la sección Notas adicionales.
En el siguiente ejemplo, se conecta al cliente con el servicio creado anteriormente por
extender la clase Binder, por lo que lo único que debe hacer es transmitir el contenido
IBinder
a la clase LocalBinder
y solicita la instancia 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 este ServiceConnection
, el cliente puede establecer una vinculación con un servicio pasándolo a bindService()
, como se muestra en el siguiente ejemplo:
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);
- El primer parámetro de
bindService()
es unIntent
que menciona explícitamente el servicio para vincular.Precaución: Si utilizas un intent para la vinculación con un
Service
, asegúrate de que tu app sea segura mediante una solicitud explícita. . El uso de un intent implícito para iniciar un servicio es una un riesgo de seguridad porque no puede estar seguro de qué servicio responde a la intent y el usuario no puede ver qué servicio se inicia. A partir de Android 5.0 (API nivel 21), el sistema lanza una excepción si llamas abindService()
con un intent implícito. - El segundo parámetro es el objeto
ServiceConnection
. - El tercer parámetro es una marca que indica opciones para la vinculación (por lo general,
BIND_AUTO_CREATE
) para crear el servicio si aún no lo está. y que estén vivas. Otros valores posibles sonBIND_DEBUG_UNBIND
,BIND_NOT_FOREGROUND
o0
para ninguno.
Notas adicionales
Aquí te proporcionamos algunas notas importantes acerca de cómo establecer enlaces con un servicio:
- Siempre capturar las excepciones
DeadObjectException
que se producen cuando se interrumpe la conexión. Esta es la única excepción que producen los métodos remotos. - Los objetos se cuentan como referencia entre procesos.
- Normalmente, sincronizas la vinculación y la desvinculación durante el
que coinciden con los momentos de inicio y cierre del ciclo de vida del cliente, como se describe en el
los siguientes ejemplos:
- Si necesitas interactuar con el servicio solo mientras tu actividad esté visible, establece la vinculación durante
onStart()
y desvincúlala duranteonStop()
. - Si quieres que tu actividad reciba respuestas aunque esté detenida en la
en segundo plano, vincular durante
onCreate()
y desvincular duranteonDestroy()
. Ten en cuenta que esto implica que tu necesita usar el servicio todo el tiempo que se ejecuta, incluso en segundo plano, por lo que el servicio está en otro proceso; entonces, aumentas el peso del proceso y se tienen más probabilidades de ser eliminados por el sistema.
Nota: Por lo general, no realizas la vinculación ni desvinculación. durante las devoluciones de llamada
onResume()
yonPause()
de tu actividad, porque estas ocurren en cada transición del ciclo de vida. Reduce al mínimo el procesamiento que se produce en estas transiciones.Además, si varias actividades de tu aplicación se vinculan al mismo servicio la transición entre dos de esas actividades, el servicio podría destruirse y volver a crearse como el desvinculación de la actividad (durante la pausa) antes de que se vincule el siguiente (durante la reanudación). Esta transición de actividad explica que las actividades coordinan sus ciclos de vida se describe en El ciclo de vida de la actividad.
- Si necesitas interactuar con el servicio solo mientras tu actividad esté visible, establece la vinculación durante
Para obtener más ejemplos de código que muestre cómo establecer una vinculación con un servicio, consulta la
RemoteService.java
en ApiDemos
Administra el ciclo de vida de un servicio vinculado
Cuando se desvincula un servicio de todos los clientes, el sistema Android lo destruye
(a menos que se haya comenzado a usar
startService()
).
No tiene que administrar el ciclo de vida de su servicio si está
que son puramente un servicio de enlace. El sistema Android lo administra por ti según
si está vinculado a algún cliente.
Sin embargo, si decides implementar el método de devolución de llamada onStartCommand()
, debes detener el servicio de forma explícita, ya que el elemento
servicio ahora se considera iniciado. En este caso, el servicio se ejecuta hasta que se detenga por sí mismo con stopSelf()
o cuando otro componente llame a stopService()
, independientemente de que esté vinculado o no a algún cliente.
Además, si tu servicio se inicia y acepta la vinculación, entonces cuando el sistema llame
tu método onUnbind()
, también puedes mostrar
Es true
si deseas recibir una llamada a onRebind()
la próxima vez que un cliente se vincule al servicio. onRebind()
muestra void, pero el cliente de todos modos recibe el IBinder
en su devolución de llamada onServiceConnected()
.
En la figura que aparece a continuación, se ilustra la lógica para este tipo de ciclo de vida.
Para obtener más información sobre el ciclo de vida de un servicio iniciado, consulta Descripción general de los servicios.