Service 作为Android中四大组件之一,日常开发中经常会使用到,本文主要讲解Service的两种启动方式,以及两种启动方式的区别,生命周期,以及适用的场景。
Service 是运行在主线程上的,是要依托android程序运行的,所以不能做耗时操作。
分别有两种启动方式:
一种startService() ,一种是bindService()。
两种启动方式的生命周期不同:
1、startService() 的生命周期 :onCreate() -> onStartCommand() (onStart()
方法已过时)-> onDestroy()
此方式的特征:与调起该服务的context没有任何关系,调起的Context(Activity等)销毁后,该服务也可以存活,但是无法与调起的Context进行通讯
2、bindService()的生命周期:onCreate() -> onBind() -> onUnbind() -> onDestroy()
此方式的特征:
1.与调起该服务的Context(Activity等)绑定在一起的,可以与调起Context进行通讯,且调起Context销魂时该服务会自动解绑。
2.绑定服务时不会调用onstartcommand()
方法。
第一种:startService()
注意:多次使用startService启动同一个service时,如果该服务已被启动,将不在执行onCreate,但每次都会执行onStartCommand步骤。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
返回值是一个int类型的:
- START_STICKY: 当Service因内存不足而被系统kill后,一段时间后内存再次空闲时,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand方法,但其中的Intent将是null,除非有挂起的Intent,如pendingintent,这个状态下比较适用于不执行命令、但无限期运行并等待作业的媒体播放器或类似服务。
- START_NOT_STICKY:当Service因内存不足而被系统kill后,即使系统内存再次空闲时,系统也不会尝试重新创建此Service。除非程序中再次调用startService启动此Service,这是最安全的选项,可以避免在不必要时以及应用能够轻松重启所有未完成的作业时运行服务。
- START_REDELIVER_INTENT:当Service因内存不足而被系统kill后,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand(),任何挂起 Intent均依次传递。
- START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
参数含义:
- intent: 启动时,启动组件传递过来的Intent,如Activity可利用Intent封装所需要的参数并传递给Service。
- flags: 表示启动请求时是否有额外数据,可选值有 0,START_FLAG_REDELIVERY,START_FLAG_RETRY,0代表没有.START_FLAG_REDELIVERY: 这个值代表了onStartCommand方法的返回值为START_REDELIVER_INTENT,意味着当Service因内存不足而被系统kill后,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。START_FLAG_RETRY : 该flag代表当onStartCommand调用后一直没有返回值时,会尝试重新去调用onStartCommand()。
- startId:指明当前服务的唯一ID,与stopSelfResult (int startId)配合使用,stopSelfResult 可以更安全地根据ID停止服务。
使用方式:
Intent intent = new Intent(context, YourCustomService.class);
startService(intent);
终止服务时必须调用stopService来终止:
Intent intent = new Intent(context, YourCustomService.class);
stopService(intent);
第二种:bindService()
使用此方式调起,Service必须重写onBind方式,实现自己的Binder,例如:
public class MyBindService extends Service {
private MyBinder mBinder = new MyBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* 创建Binder对象,给绑定的Activity使用。
*/
public class MyBinder extends Binder {
/**
* 提供一个方法,返回当前MyBindService对象,这样我们就可在被调用Activity中使用Service对象
*
*/
MyBindService getService(){
return MyBindService.this;
}
}
}
在Activity中ServiceConnection来绑定service。
MyBindService mBindService;
ServiceConnection mConn = new ServiceConnection(){
/**
* 与服务器端交互的接口方法 绑定服务的时候被回调,在这个方法获取绑定Service传递过来的IBinder对象,
* 通过这个IBinder对象,实现宿主和Service的交互。
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyBindService.MyBinder binder = (MyBindService.MyBinder)service;
mBindService = binder.getService();
// 可以使用mBindService对象来进行通讯
}
/**
* 此方法当取消绑定的时候被回调。但正常情况下是不被调用的,它的调用时机是当Service服务被意外销毁时,
* 例如内存的资源不足时这个方法才被自动调用。
*/
@Override
public void onServiceDisconnected(ComponentName name) {
mBindService = null;
}
};
//绑定启动Service方式如下:
Intent intent = new Intent(Context,MyBindService.class);
bindService(intent,mConn, Service.BIND_AUTO_CREATE);
//解绑Service的方式
if(mBindService != null){
mBindService = null;
unbindService(mConn);
}