一、作用
Android 四大组件之一,是Context
类的子类。非常适合于执行不需要和用户交互,且要长期运行的任务。Service
默认运行在 UI 线程,故,如果有耗时操作的话,开启子线程。
二、相关概念
1. Service 生命周期
-
onCreate()
:只能被回调一次,在其中进行初始化操作 -
onStartCommand()
:可被多次回调,每调用startService()
启动服务一次就被回调一次,可将主要业务逻辑写在这个里面。
由于手机 RAM、资源有限,所以很多 Service 因为资源不足被 kill,此时,onStartCommand()
的返回值决定了 Service 被 kill 后的处理方式(Android 综合揭秘 —— 全面剖释 Service 服务):
START_STICKY
如果service进程被kill掉,系统会尝试重新创建Service,如果在此期间没有任何启动命令被传递到Service,那么参数intent将为null。
START_NOT_STICKY
使用这个返回值时,如果在执行完onStartCommand()后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT
使用这个返回值时,如果在执行完onStartCommand()后,服务被异常kill掉,系统会自动重启该服务,并将intent的值传入。
START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
而输入参数flags正是代表此次onStartCommand()方法的启动方式,正常启动时,flags默认为0,被kill后重新启动,参数分为以下两种:
START_FLAG_RETRY
代表service被kill后重新启动,由于上次返回值为START_STICKY,所以参数 intent 为null
START_FLAG_REDELIVERY
代表service被kill后重新启动,由于上次返回值为START_REDELIVER_INTENT,所以带输入参数intent
-
onBind()
:只能被回调一次,客户端通过调用bindService()
时被回调,下次再调用bindService()
不会回调该方法。通过该方法向客户端返回一个IBinder
实例,客户端通过该实例调用服务端的方法。 -
onUnBind()
:只能被回调一次,客户端通过调用unBindService()
与服务端解除绑定时回调。若重复解绑会抛出异常。该方法默认返回 false, 当返回值 true 后,再次调用 Context.bindService 时将触发onRebind()
方法。 -
onRebind()
:
-
onDestroy()
:只能被回调一次,在其中完成资源清理工作,如取消注册监听器、关闭线程等。
2. 不同启动方式下 Service 的生命周期
按照启动方法将 Service 分类,不同启动方法下 Service 的生命周期不同。

(1)startService()方式启动
-
生命周期
onCreate()
->onStartCommand()
->onDestroy()
-
停止服务方法
Service中调用stopSelf()
,或启动者调用stopService()
(2)bindService
-
生命周期
onCreate()
->onBind()
->onUnBind()
->onDestroy()
-
停止服务方法:
调用unbindService()
来接触绑定;断开连接或调用该 Service 的 Context 不存在了,通过bindService()
方法启动的 Service 的生命周期依附于启动它的 Context。
当 Service 和其他组件绑定时,Service 充当服务提供者的角色
(3)二者混合使用
-
生命周期
onCreate()
->onStartCommand()
->onBind()
->onUnBind()
->onDestroy()
-
停止服务方法
调用unBindService()
将不会停止 Service,必须调用stopService()
或 Service 自身的stopSelf()
来停止服务。
三、使用
1. 后台运行的服务
public class BackService extends Service {
private Thread mThread;
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 在子线程中进行逻辑操作
mThread = new Thread() {
@Override
public void run() {
while (true) {
// 等待停止线程
if (this.isInterrupted()) {
try {
throw new InterruptedException();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 耗时操作
System.out.println("xxx");
}
}
};
mThread.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
// 资源清理
mThread.interrupt();
}
@Override
public IBinder onBind(Intent intent) {
// 返回null
return null;
}
}
-
新建类继承
Service
类,onBind()
方法是Service
类中的唯一一个抽象方法,必须要在子类中实现。 -
在
onStartCommand()
中书写业务逻辑,本例中创建了子线程来完成耗时操作。 -
当 Service 关闭后,如果在
onDestory()
方法中不关闭线程,你会发现我们的子线程进行的耗时操作是一直存在的,此时关闭该子线程的方法需要直接关闭该应用程序。因此,在onDestory()
方法中要进行必要的清理工作。 -
前台调用
Intent intent = new Intent(this, BackService.class);
// Intent 中携带数据
startService(intent);
2. 可交互的后台服务
当 Service 和其他组件绑定时,Service 充当服务提供者的角色。返回给客户端一个
IBinder
接口类型数据。
采用第一行代码中的实例。希望 DownloadService 提供下载功能,在 Activity 中可以决定下载何时开始
,以及随时可以查看下载速度
。创建一个专门的Binder
对象来对所提供的功能进行管理,Binder
实现了IBinder
接口。
- 创建提供服务的 Service
public class DowloadService extends Service {
private DownloadBinder mBinder = new DownloadBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class DownloadBinder extends Binder {
// 开始下载
public void startDownload() {
}
// 下载进度
public int getProgress() {
return 0;
}
}
}
- 客户端连接服务端,并调用服务端提供的方法
private DowloadService.DownloadBinder downloadBinder;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// 绑定成功
downloadBinder = (DowloadService.DownloadBinder) iBinder;
// 调用服务端提供的方法
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
// 解除绑定
}
};
public void download() {
// 绑定service
Intent intent = new Intent(this, DowloadService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}
ServiceConnection
:由服务使用者创建,以获取消息反馈。
onServiceConnected()
:活动与服务使用者绑定成功时回调,绑定成功后即可调用服务提供者 Service 的服务,通过 Binder 对象调用;onServiceDisconnected()
:解绑成功时回调
3. 前台服务
在状态栏有正在运行的系统图标。Service 启动后在状态栏开启一个通知。
@Override
public void onCreate() {
super.onCreate();
// ...
startForeground(1, notifycation);
}
网友评论