服务是在后台运行以执行长时间运行的操作而无需与用户交互的组件,并且即使应用程序被破坏,它也可以工作。服务实际上可以采取两种状态-
| Sr.No. | State & Remark |
|---|---|
| 1 |
Started 当应用程序组件(如Activity)通过调用 startService()启动服务,启动后即使启动该服务的组件被破坏,服务也可以无限期在后台运行。 |
| 2 |
Bound 当应用程序组件通过调用 bindService()绑定到服务时,该服务被绑定,绑定的服务提供了一个Client-Server接口,该接口允许组件与该服务进行交互,发送请求,获取输出,甚至跨进程间通信(IPC)进行交互。 |
服务具有生命周期回调方法,您可以实施这些方法来监视服务状态的变化,并且可以在适当的阶段执行工作,左图显示了使用startService()创建服务时的生命周期,右图显示了使用bindService()创建服务时的生命周期:(图片由android.com提供)

要创建服务,请创建一个Java类,该类扩展Service基类或其现有子类之一,Service 基类定义了各种回调方法,最重要的如下,您不需要实现所有的回调方法。但是,重要的是您必须了解每一个,并实施那些确保您的应用程序符合用户期望的行为。
| Sr.No. | Callback & 描述 |
|---|---|
| 1 |
onStartCommand() 当另一个组件(如Activity)通过调用 startService()请求启动服务时,系统将调用此方法。如果实现此方法,则有责任通过调用 stopSelf()或 stopService()方法来停止服务。 |
| 2 |
onBind() 当另一个组件想要通过调用 bindService()与服务绑定时,系统将调用此方法。如果实现此方法,则必须通过返回 IBinder 对象,提供客户端用于与服务进行通信的接口。您必须始终实现此方法,但是如果您不想允许绑定,则应返回 null 。 |
| 3 |
onUnbind() 当所有客户端都已与服务发布的特定接口断开连接时,系统将调用此方法。 |
| 4 |
onRebind() 在新的客户端已经连接到服务之后,系统会在先前已通知所有客户端在其 onUnbind(Intent)中断开连接后调用此方法。 |
| 5 |
onCreate() 首次使用 onStartCommand()或 onBind()创建服务时,系统会调用此方法。 |
| 6 |
onDestroy() 当不再使用该服务并将其销毁时,系统将调用此方法。 |
以下框架服务演示了每种生命周期方法-
package com.learnfk;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() {
} }
本示例将引导您完成一些简单的步骤,以展示如何创建自己的Android服务。
以下是修改后的主要Activity文件 MainActivity.java 的内容,该文件可以包括每个基本生命周期方法,无涯教程添加了 startService()和 stopService()方法来启动和停止服务。
package com.example.learnfk7.myapplication;import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle;
import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.View;
public class MainActivity extends Activity { String msg = "Android : ";
/** 在第一次创建Activity时调用。 */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(msg, "The onCreate() event"); }
public void startService(View view) { startService(new Intent(getBaseContext(), MyService.class)); }
//停止服务的方法 public void stopService(View view) { stopService(new Intent(getBaseContext(), MyService.class)); } }
以下是 MyService.java 的内容,该文件可以根据要求实现与服务相关联的一种或多种方法,现在,无涯教程将仅实现两种方法 onStartCommand()和 onDestroy()-
package com.example.learnfk7.myapplication;import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.widget.Toast;
/**
- Created by LearnFk7 on 8/23/2021. */
public class MyService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; }
@Override public int onStartCommand(Intent intent, int flags, int startId) { //让它继续运行直到它停止。 Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show(); return START_STICKY; }
@Override public void onDestroy() { super.onDestroy(); Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show(); } }
以下将修改AndroidManifest.xml文件的内容,在这里无涯教程添加了<service ... />标签以包括无涯教程的服务-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.learnfk7.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
</span><span class="tag"><activity</span><span class="pln"> </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">".MainActivity"</span><span class="tag">></span><span class="pln">
</span><span class="tag"><intent-filter></span><span class="pln">
</span><span class="tag"><action</span><span class="pln"> </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">"android.intent.action.MAIN"</span><span class="pln"> </span><span class="tag">/></span><span class="pln">
</span><span class="tag"><category</span><span class="pln"> </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">"android.intent.category.LAUNCHER"</span><span class="pln"> </span><span class="tag">/></span><span class="pln">
</span><span class="tag"></intent-filter></span><span class="pln">
</span><span class="tag"></activity></span><span class="pln">
</span><span class="tag"><service</span><span class="pln"> </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">".MyService"</span><span class="pln"> </span><span class="tag">/></span><span class="pln">
</application>
</manifest>
以下是 res/layout/activity_main.xml 文件的内容,其中包括两个按钮-
<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="Example of services" 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="Learnfk point " 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/abc" 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="Start Services" 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="Stop Services" 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>
让无涯教程尝试运行刚刚修改的修改后的 Hello World!应用程序,无涯教程假设您在进行环境设置时创建了 AVD,要从Android Studio运行该应用,请打开您项目的Activity文件之一,然后单击运行
工具栏。 Android Studio将应用程序安装在您的AVD上并启动它,如果设置和应用程序一切正常,它将显示在"Emulator"窗口下面-

现在开始您的服务,让无涯教程单击开始服务按钮,这将启动服务,并且根据无涯教程在 onStartCommand()方法中的编程,消息服务已开始将出现在模拟器的底部,如下所示:

要停止服务,可以单击"停止服务"按钮。