和大家熟悉的Activity组件一样,service也是Android应用开程序发中常用的组件,它和acitivy一样也有自己的生命周期,不同的是service是运行在后台的,没有同用户直接交互的界面。
service的是有两种启动方式:
onCreate()----onStartCommand()-----onStop()----onDestory()
当调用者通过其他组件来调用一次startService之后,首先触发onCreate(),然后是调触发onStartCommand()
调用者停止服务后 触发onStop和onDestory
这个过程中,无论startSrvice被调用多少次,onCreate只会执行一次,但是onStartCommand会执行多次,直到有人停止service触发了onStop和onDestory。service才会重走生命周期
下面重点说一下onStartCommand()这个方法,这个函数有一个int的返回值,根据不同的返回值对应不同的情况:
如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
当调用者在外部通过stopService()或者在service内部通过StopSelf()方式停止了service,这个时候service是不回自动重启。
所以为了程序的性能,我们在掉用了startService之后,一定要记得stopService,以免引起不可预知的错误。
onCreate()----onBind()-----onUnbind()----onStop()----onDestory()
当调用者通过其他组件来调用一次bindService之后,首先触发onCreate(),然后是调触发onBind()
调用者解除绑定后 触发onUnbind--onStop和onDestory
这个过程中,无论bindService被调用多少次,onCreate只会执行一次,同样onBind()也只会执行一次,直到有人解除绑定service触发了onUnbind,直到onDestory。service才会重走生命周期,具体调用方式如下:
以在activity中绑定service为例
Intent mIntent = new Intent(context, GlassService.class);
bindService(mIntent, serviceConnection, Context.BIND_AUTO_CREATE);
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mGlassService = ((GlassService.MyBinder) iBinder).getGlassService();
if (mGlassService != null) {
......
......
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
.......
......
}
};
注意此处有坑,当我们使用同一个context和serviceconnection去执行bindservice时,onServiceConnected方法只会被回调一次,除非我们传入不同的context和serviceconnection去调用bindService才会去触发onServiceConected回调。因为onBind方法是返回的IBinder对象是通过onServiceConnected会来回调给调用者,当serviceConnection对象不变时,此回调是不会多次调用的
,所以这个时候可以设置一个flag标志位,来判断是否需要多次bindService,在上面代码的基础上改动如下:
if (isRegist) {
if (mGlassService != null) {
mGlassService.setIStausCallback(iStausCallback);
mGlassService.connectWifi();
}
} else {
Intent mIntent = new Intent(context, GlassService.class);
this.iStausCallback = iStausCallback;
context.bindService(mIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
isRegist = true;
mGlassService = ((GlassService.MyBinder) iBinder).getGlassService();
if (mGlassService != null) {
mGlassService.setIStausCallback(iStausCallback);
mGlassService.connectWifi();
mGlassService.setReleaseListener(GlassServiceState.this);
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
isRegist = false;
}
};
所以当我们通过bindService启动service之后,一定要记得调用onUnbind方法来解除绑定,这样才能保证onServiceConnected回调能正常执行。
这个时候如果调用unUnbind方法,service并不会被销毁,也就说不会执行onDestory方法,直到用户调用了StopService之后,Servie才会被销毁。
这个时候如果调用了StopService,service也不会被销毁,直到用户调用onUnbind方法,service才会被销毁.。
总结:当我们只是单纯的想启动一个服务在后台执行任务,无需和调用者进行数据交互,可以使用StartService方式
当想使用Service内部定义的功能的时候,也就是说需要和Service有交互的时候,可以使用bindService方式来使用。
也可以两种方式结合来使用。