Android Servicio (Service)
Un servicio es un componente que se ejecuta en segundo plano, realiza tareas de larga duración que no requieren interacción del usuario. Puede seguir funcionando incluso si la aplicación es destruida. Un servicio básicamente incluye dos estados:
| Estado | Descripción |
|---|---|
| Started | Cuando un componente de la aplicación de Android, como una actividad, inicia un servicio mediante startService(), el servicio se encuentra en estado Started (Iniciado). Una vez iniciado, el servicio puede ejecutarse en segundo plano indefinidamente, incluso si el componente que lo inició ha sido destruido. |
| Bound | Cuando un componente de la aplicación de Android vincula un servicio mediante bindService(), el servicio se encuentra en estado Bound (Vinculado). Un servicio en estado Bound proporciona una interfaz cliente-servidor que permite a los componentes interactuar con el servicio, como enviar solicitudes, obtener resultados e incluso realizar comunicación entre procesos mediante IPC. |
El servicio tiene métodos de ciclo de vida que permiten monitorear los cambios de estado del servicio y ejecutar trabajo en las fases adecuadas. El diagrama izquierdo a continuación muestra el ciclo de vida cuando un servicio se crea mediante startService(), y el diagrama derecho muestra el ciclo de vida cuando un servicio se crea mediante bindService():
Para crear un servicio, debes crear una clase Java que herede de la clase base Service o de una de sus subclases conocidas. La clase base Service define diferentes métodos de devolución de llamada (callbacks) y la mayoría de los métodos importantes. No necesitas implementar todos los métodos de devolución de llamada. Sin embargo, es muy importante comprender todos los métodos. Implementar estos callbacks asegura que tu aplicación se comporte de la manera que el usuario espera.
| Callback | Descripción |
|---|---|
| onStartCommand() | Cuando otros componentes (como actividades) solicitan iniciar un servicio llamando a startService(), el sistema llama a este método. Si implementas este método, eres responsable de detener el servicio mediante stopSelf() o stopService() cuando el trabajo haya terminado. |
| onBind | Cuando otros componentes quieren vincularse al servicio mediante bindService(), el sistema llama a este método. Si implementas este método, debes devolver un objeto IBinder para proporcionar una interfaz que permita a los clientes comunicarse con el servicio. Debes implementar este método; si no permites el enlace, simplemente devuelve null. |
| onUnbind() | Cuando todos los clientes se desvinculan de la interfaz especial publicada por el servicio, el sistema llama a este método. |
| onRebind() | Cuando un nuevo cliente se conecta al servicio y previamente se le había notificado la desconexión mediante onUnbind(Intent), el sistema llama a este método. |
| onCreate() | Cuando el servicio se crea por primera vez a través de onStartCommand() y onBind(), el sistema llama a este método. Esta llamada requiere una configuración única. |
| onDestroy() | Cuando el servicio ya no es útil o es destruido, el sistema llama a este método. Tu servicio debe implementar este método para liberar cualquier recurso, como hilos, listeners registrados, receptores, etc. |
El siguiente servicio principal demuestra el ciclo de vida de cada método:
package com.ejemplo.androidservices;
import android.app.Service;
import android.os.IBinder;
import android.content.Intent;
import android.os.Bundle;
public class HelloService extends Service {
/** 标识服务如果被杀死之后的行为 */
int mStartMode;
/** 绑定的客户端接口 */
IBinder mBinder;
/** 标识是否可以使用onRebind */
boolean mAllowRebind;
/** 当服务被创建时调用. */
@Override
public void onCreate() {
}
/** 调用startService()启动服务时回调 */
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return mStartMode;
}
/** 通过bindService()绑定到服务的客户端 */
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** 通过unbindService()解除所有客户端绑定时调用 */
@Override
public boolean onUnbind(Intent intent) {
return mAllowRebind;
}
/** 通过bindService()将客户端绑定到服务时调用*/
@Override
public void onRebind(Intent intent) {
}
/** 服务不再有用且将要被销毁时调用 */
@Override
public void onDestroy() {
}
}
Ejemplo
Este ejemplo te mostrará, con sencillos pasos, cómo crear tu propio servicio de Android. Sigue los pasos a continuación para modificar la aplicación de Android creada anteriormente en el capítulo de ejemplo Hello World:
| Pasos | Descripción |
|---|---|
| 1 | Usa el IDE Android Studio para crear una aplicación de Android y nómbrala androidservices en el paquete com.ejemplo.androidservices. Similar al capítulo de ejemplo Hello World. |
| 2 | Modifica el archivo de la actividad principal MainActivity.java para añadir los métodos startService() y stopService(). |
| 3 | Crea un nuevo archivo Java MyService.java en el paquete com.ejemplo.androidservices. Este archivo implementará los métodos relacionados con los servicios de Android. |
| 4 | En el archivo AndroidManifest.xml, usa la etiqueta <service.../> para definir el servicio. La aplicación puede tener uno o más servicios, sin ninguna limitación. |
| 5 | Modifica el diseño predeterminado en el archivo res/layout/activity_main.xml para incluir dos botones en un diseño lineal. |
| 6 | No modifiques ninguna constante en el archivo res/values/strings.xml. Android Studio se encargará de los valores de cadena. |
| 7 | Inicia el emulador de Android para ejecutar la aplicación y verifica el resultado de los cambios realizados en la aplicación. |
A continuación se muestra el contenido modificado del archivo de la actividad principal src/com.ejemplo.androidservices/MainActivity.java. Este archivo contiene todos los métodos básicos del ciclo de vida. Hemos añadido los métodos startService() y stopService() para iniciar y detener el servicio.
package com.ejemplo.androidservices;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.content.Intent;
import android.view.View;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
// Method to start the service
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
// Method to stop the service
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
}
A continuación se muestra el contenido de src/com.ejemplo.androidservices/MyService.java. Este archivo puede implementar uno o más métodos relacionados con el servicio según los requisitos. Para los principiantes, solo implementamos onStartCommand() y onDestroy():
package com.ejemplo.androidservices;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "服务已经启动", Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "服务已经停止", Toast.LENGTH_LONG).show();
}
}
A continuación se modificará el archivo AndroidManifest.xml. Aquí se añade la etiqueta <service.../> para incluir nuestro servicio:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ejemplo.androidservices"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="22" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".MyService" />
</application>
</manifest>
A continuación se muestra el contenido del archivo res/layout/activity_main.xml, que contiene dos botones:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android 服务实例"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="www.example.com"
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_above="@+id/imageButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/ic_launcher.html"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="启动服务"
android:onClick="startService"
android:layout_below="@+id/imageButton"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服务"
android:id="@+id/button"
android:onClick="stopService"
android:layout_below="@+id/button2"
android:layout_alignLeft="@+id/button2"
android:layout_alignStart="@+id/button2"
android:layout_alignRight="@+id/button2"
android:layout_alignEnd="@+id/button2" />
</RelativeLayout>
A continuación se muestra el contenido de res/values/strings.xml para definir dos nuevas constantes:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Android Services</string>
<string name="title_activity_main">MainActivity</string>
<string name="menu_settings">Settings</string>
<string name="action_settings">Settings</string>
</resources>
Ejecutemos la aplicación My Application que acabamos de modificar. Supongo que ya has creado el AVD durante la instalación del entorno. Abre el archivo de actividad de tu proyecto y haz clic en el
icono de la barra de herramientas para ejecutar la aplicación en Android Studio. Android Studio instala la aplicación en el AVD y la inicia. Si todo va bien, se mostrará lo siguiente en la ventana del emulador:

Ahora haz clic en el botón "Iniciar servicio" para iniciar el servicio. Esto ejecutará el método onStartCommand() que hemos escrito, y aparecerá un mensaje "El servicio se ha iniciado" en la parte inferior del emulador, como se muestra a continuación:

Haz clic en el botón "Detener servicio" en la parte inferior para detener el servicio.
Otras extensiones