Service是一种计算型组件,用于后台执行一系列计算任务,因为运行在后台,所以无法被用户感知,Service组件有两种状态:启动状态和绑定状态.Service运行在主线程中,因此耗时的后台计算任务仍然需要在单独的子线程中完成.
- Service的生命周期
- Service的基本用法
- Service和Activity通信
- Service的重启
一.Service的生命周期
官方文档关于Service生命周期的图例:
看图可以知道有两种方式可启动Service,这也就对应着Service的两种状态:
1.启动状态
通过startService()方法可以启动一个Service, 启动状态的Service主要是做一些后台计算,不需要与外界有直接的交互,他所经历的生命周期为:
onCreate() --> onStartCommand() --> onDestroy()
通过stopService()或stopSelf()可以停止一个Service,无论调用多少次startService()方法,调用一次stopService()或stopSelf()方法,服务就停止了.
2.绑定状态
通过bindService()方法可以绑定一个Service,绑定状态的Service同样可以做一些后台计算,但是外界可以很方便的和Service组件进行通信,他所经历的生命周期为:
onCreate() --> onBind() --> onUnbind() --> onDestroy()
通过unbindService()可以停止服务.
注意:这两种启动方法不冲突,就是说用startService()方法启动Service后,还可以用bindService()方法绑定,但是要同时调用stopService()方法和unbindService()方法才能停止服务.
二.Service的基本用法
1.普通Service
(1)新建一个Service
public class MyService extends Service {
@androidx.annotation.Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
(2)在配置文件中进行注册
<service android:name=".MyService"></service>
(3)启动Service
Intent intent = new Intent(this, MyService.class);
startActivity(intent);
(4)停止Service
Intent intent = new Intent(this, MyService.class);
stopService(intent);
2.前台Service
前台Service和普通Service的区别在于,前台Service会有一个正在运行的图标一直在系统状态栏显示,下拉状态栏可以看到更加详细的信息,使用前台服务是为了防止服务被系统回收掉,比如听歌,实时的天气状况.
实现前台服务是构建一个Notification,再调用startForeground()方法
@Override
public void onCreate() {
super.onCreate();
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentText("this is notification");
builder.setContentTitle("notification:");
builder.setWhen(System.currentTimeMillis());
Notification build = builder.build();
startForeground(1,build);
}
3.系统Service
通过getSystemService()方法,传入一个name可以得到相应的系统服务,常用的系统服务有:
现在来通过学习AlarmManager系统服务,来实现一个后台定时任务.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
AlarmManager systemService = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long time = SystemClock.elapsedRealtime()+10*1000;//开机至今的时间加上延迟执行的时间
Intent intent1 = new Intent(this, MyBroadcast.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,intent1,0);//获取一个能过够执行的广播
systemService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,time,pendingIntent);
return super.onStartCommand(intent, flags, startId);
}
4.IntentService
IntentService是一个异步的,会自动停止的服务.使用方法和普通服务一样,区别在于要提供一个无参的构造函数且在其内部必须调用父类的有参构造函数,然后具体的实现在onHandleIntent()方法,这个方法是在子线程中运行,可以做耗时的操作.IntentService服务在运行结束后会自动停止.
public class MyIntentService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@androidx.annotation.Nullable Intent intent) {
}
}
三.Service与Activity通信
Service与Activity的通信,需要绑定服务,借助onBind()方法,这里写一个简单的例子:
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return new MyBind();
}
class MyBind extends Binder{
void updateDate(){
Log.d("MyService","更新数据");
}
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBind bind = (MyService.MyBind)service;
bind.updateDate();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);//最后一个参数表示活动和服务绑定后自动创建服务
}
四.Service的重启
通过startService启动服务,调用服务的onStartCommand()方法,这个方法有一个int的返回值,这个值有四种:
(1)START_STICKY:粘性的,表示Service被异常杀掉,系统会自动重启Service,但是参数Intent值为null.
(2)START_NOT_STICKY:非粘性的,表示服务被异常杀掉,系统不会重启服务.
(3)START_REDELIVER_INTENT:表示服务被异常杀掉,系统会重启服务,且重传Intent.
(4)START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但是不保证服务被异常杀掉后会重启.