Cómo crear un servicio en segundo plano

La clase IntentService proporciona una estructura sencilla para ejecutar una operación en un solo subproceso en segundo plano. Esto te permite manejar operaciones de larga duración sin afectar la capacidad de respuesta de la interfaz de usuario. Además, un objeto IntentService no se ve afectado por la mayoría de los eventos del ciclo de vida de la interfaz de usuario, por lo que continúa ejecutándose en circunstancias en las que se cerraría un elemento AsyncTask.

Un elemento IntentService tiene las siguientes limitaciones:

  • No puede interactuar directamente con tu interfaz de usuario. Para colocar sus resultados en la IU, debes enviarlos a un objeto Activity.
  • Las solicitudes de trabajo se ejecutan secuencialmente. Si una operación se está ejecutando en un elemento IntentService y le envías otra solicitud, la solicitud espera hasta que finalice la primera operación.
  • Una operación que se ejecuta en un elemento IntentService no se puede interrumpir.

Sin embargo, en la mayoría de los casos, un elemento IntentService es la forma preferida de realizar operaciones simples en segundo plano.

En esta guía, se explica cómo hacer lo siguiente:

Cómo controlar intents entrantes

Si quieres crear un componente IntentService para tu app, define una clase que extienda IntentService y, dentro de ella, define un método que anule onHandleIntent(). Por ejemplo:

Kotlin

    class RSSPullService : IntentService(RSSPullService::class.simpleName)

        override fun onHandleIntent(workIntent: Intent) {
            // Gets data from the incoming Intent
            val dataString = workIntent.dataString
            ...
            // Do work here, based on the contents of dataString
            ...
        }
    }
    

Java

    public class RSSPullService extends IntentService {
        @Override
        protected void onHandleIntent(Intent workIntent) {
            // Gets data from the incoming Intent
            String dataString = workIntent.getDataString();
            ...
            // Do work here, based on the contents of dataString
            ...
        }
    }
    

Ten en cuenta que las otras devoluciones de llamada de un componente Service habitual, como onStartCommand(), se invocan automáticamente mediante IntentService. En un elemento IntentService, debes evitar anular estas devoluciones de llamada.

Para obtener más información sobre cómo crear un elemento IntentService, consulta Cómo extender la clase IntentService.

Cómo definir el servicio de intents en el manifiesto

Un elemento IntentService también necesita una entrada en el manifiesto de tu app. Proporciona esta entrada como un elemento <service> que sea un elemento secundario de <application>:

        <application
            android:icon="@drawable/icon"
            android:label="@string/app_name">
            ...
            <!--
                Because android:exported is set to "false",
                the service is only available to this app.
            -->
            <service
                android:name=".RSSPullService"
                android:exported="false"/>
            ...
        </application>
    

El atributo android:name especifica el nombre de clase del elemento IntentService.

Ten en cuenta que el elemento <service> no contiene un filtro de intents. El objeto Activity que envía solicitudes de trabajo al servicio utiliza un Intent explícito, por lo que no se necesita ningún filtro. Esto también significa que solo los componentes de la misma app o de otras apps con el mismo ID de usuario pueden acceder al servicio.

Ahora que tienes la clase IntentService básica, puedes enviarle solicitudes de trabajo con objetos Intent. El procedimiento para construir estos objetos y enviarlos a tu elemento IntentService se describe en Cómo enviar solicitudes de trabajo al servicio en segundo plano.