最近给app添加计步的功能,开一个service,然后用ipc进程间通信,重新复习了一下android四大组件之一的service;
先来看service的生命周期:
service的生命周期,从它被创建开始,到它被销毁,可以有两条不同的路径:
A started service
被开启的service通过其他组件调用startService()被创建
这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它.
当service被停止时,系统会销毁它。
A bound service
被绑定的service是当其他组件调用bindService()来创建的。
客户可以通过IBinder接口和service进行通信。
客户可以通过unbindService()方法来关闭连接。
一个service可以同时和多个客户绑定,当多个客户都解除绑定后,系统会销毁service。
当然,可以同时调用startService和bindService开启和绑定service
onCreate()
不管你是开启还是绑定服务,最开始的回调函数肯定是onCreate(),并且该回调只会执行一次,之后再执行开启或绑定服务都不会走该回调函数,除非你的service被销毁了。
onStartCommond()
每次执行startService()都会调用一次onStartCommond()。
onDestory()
service被销毁时,回调该函数
我觉得重要的还是bindService()那几个回调函数onBind(),onUnbind(),onRebind()。
看个栗子,估计大家就明白了:
一般我们在启动service都会同时调用startService和bindService,
startService之后,如果没有调用stopStervice,服务会一直在后台,除非被系统杀死,bindService是将组件和服务绑定起来,可以通过unBindService来解绑。首先在activity中我们调用了startService和bindService()后,会回调onBind()方法,
@Override
public IBinder onBind(Intent intent) {
Log.e("bindService", "onBind");
return mBinder;
}
在activity的onDestory()方法里我们调用
@Override
public void onDestroy() {
super.onDestroy();
if (isBind) { //如果绑定了
unbindService(conn); //解绑
}
}
onUnbind回调
@Override
public boolean onUnbind(Intent intent) {
Log.e("bindService", "onUnbind");
return super.onUnbind(intent);
}
然后我再打开该activity,再次执行bindService,onBind()方法并不会执行,因为我们的service通过startService已经在后台开启了,这时候再次bindServce是不会调用onBind()方法的,除非你把服务都杀掉后,才后重新走onBind方法,服务一直在后台,对应的onBind只会走一次,那么之后如果调用bindService()之后,其实走的都是onRebind()方法,当然前提是在onUnbind()的返回一定要为true
如下:
@Override
public boolean onUnbind(Intent intent) {
Log.e("bindService", "onUnbind");
return true;
}
改完之后,
可以看到,只要service没没被杀死,不管你进来几次,都是回调onRebind和onUnbind方法,并且如果你只是bindService,并没有stopService也是一样的。
因为自己正好用到了service,所以对service的生命周期又重新学习了一遍,当你对service的生命周期走向不了解的时候,建议你每一个回调方法里面都打日志,这样就很清楚了。
当时我遇到的问题是,在app打开时,点开service的前台notification,跳转到相应的计步页面,在app关闭时,点开service的前台notification,先启动app,在跳转到相应的计步页面,这个时候,其实只要在service的这几个生命周期里面加一个全局变量,判断当前app是否启动,然后在notification中进行判断就好了,回调了onUnBind,则说明app关闭了,可以在回调onUnbind的时候设置一个变量记录如isBind = false,回调了onBind或者onRebind说明app重启了,可以记录为isBind = true,这样在notification中就可以通过isBind的值来启动app还是直接跳转相应界面了。
虽然很早就了解生命周期,还是在实际运用中才能加深印象,并巩固。