四大组件之Service(二)-Service在各种情况下的生命周期
2016-06-13 13:38
281 查看
第3节 Service的生命周期
3.1 Service的生命状态
与Activity类似,
Service也是有生命周期的。在实现一个
Service的时候,可以覆盖它的生命周期函数,当它进入不同生命状态的时候,这些函数会被触发,我们就可以在它不同的生命阶段做不同的逻辑操作。
public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onRebind(Intent intent) { super.onRebind(intent); } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } }
因为
Service不像
Activity有需要显示的界面,所以它的状态少了很多,没有
onResume()
onPause()等等与界面显示相关的状态。
这里面的
onStartCommand()函数与
onUnbind()函数要特别注意,它们的返回值有特别的意义,会影响到
Service的生命周期,我们会在最后单独解释。
3.2 生命周期
通过startService()运行的
Service与通过
bindService()运行的
Service相比较,它们的生命周期有所不同。
假设
Service-MyService 还没有被启动过,我们来看看它被一个或多个组件使用
startService()
stopService()
bindService()
unbindService()这些方法后,生命周期会怎么变化。
组件名称 | 启动Service的方法 | 关闭Service的方法 |
---|---|---|
A | startService() | stopService() |
B | startService() | stopService() |
C | bindService() | unbindService() |
D | bindService() | unbindService() |
3.2.1 Start Service的生命周期
对于只使用startService()和
stopService()来控制
Service的情况:
情况1
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> A -- stopService() -> MyService -- onDestroy()
情况2
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> A -- startService() -> MyService -- onStartCommand() -> A -- stopService() -> MyService -- onDestroy()
情况3
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> B -- startService() -> MyService -- onStartCommand() -> A -- stopService() -> MyService -- onDestroy()
情况4
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> B -- startService() -> MyService -- onStartCommand() -> B -- stopService() -> MyService -- onDestroy()
可以看出,
任意组件调用
startService()后,如果这个
Service还没有创建,系统会首先创建-
onCreate();
之后触发
onStartCommand();
任意组件调用
stopService()后,如果这个
Service还没有被销毁,系统会销毁-
onDestroy();
3.2.2 Bind Service的生命周期
onStartCommand()函数与
onUnbind()函数也会对生命周期有影响,所以这里我们假设使用的是默认的返回值,
@Override public boolean onUnbind(Intent intent) { //实际上是返回false return super.onUnbind(intent); } @Override public int onStartCommand(Intent intent, int flags, int startId) { //实际上是返回START_STICKY return super.onStartCommand(intent, flags, startId); }
组件触发
Service运行的
startService()函数也会对生命周期有影响--第三个参数,所以这里我们假设使用
Context.BIND_AUTO_CREATE,
bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);
那么,对于只使用
bindService()和
unbindService()来控制
Service的情况:
情况1
C -- bindService() -> MyService -- onCreate() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> C -- unbindService() -> MyService -- onUnbind() MyService -- onDestroy()
情况2
C -- bindService() -> MyService -- onCreate() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> C -- bindService() -> MyService -- 无变化 C -- unbindService() -> MyService -- onUnbind() MyService -- onDestroy()
情况3
C -- bindService() -> MyService -- onCreate() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> D -- bindService() -> MyService -- onBind() -> D -- onServiceConnected()被触发 -> C -- unbindService() -> MyService -- onUnbind() D -- unbindService() -> MyService -- onUnbind() MyService -- onDestroy()
情况4
C -- bindService() -> MyService -- onCreate() -> MyService -- onBind() -> C -- onServiceConnected()`被触发 -> D -- bindService() -> MyService -- onBind() -> D -- onServiceConnected()被触发 -> D -- unbindService() -> MyService -- onUnbind() C -- unbindService() -> MyService -- onUnbind() MyService -- onDestroy()
可以看出,
任意组件调用
bindService()后,如果这个
Service还没有创建,系统会首先创建-
onCreate();
之后触发
onBind();
之后组件的
onServiceConnected()被触发,告知绑定成功;
任意已绑定的组件调用
unbindService()后,会触发
onUnbind();
如果这个
Service没有与其他的组件绑定,那么系统会销毁-
onDestroy();
3.2.3 混合模式下的生命周期
对于使用了startService()
stopService()与
bindService()和
unbindService()等两种方式来控制
Service的情况:
情况1
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> C -- bindService() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> C -- unbindService() -> MyService -- onUnbind() A -- stopService() -> MyService -- onDestroy()
情况2
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> C -- bindService() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> A -- stopService() -> MyService -- 无变化 C -- unbindService() -> MyService -- onUnbind() MyService -- onDestroy()
情况3
C -- bindService() -> MyService -- onCreate() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> A -- startService() -> MyService -- onStartCommand() -> C -- unbindService() -> MyService -- onUnbind() A -- stopService() -> MyService -- onDestroy()
情况4
C -- bindService() -> MyService -- onCreate() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> A -- startService() -> MyService -- onStartCommand() -> A -- stopService() -> MyService -- 无变化 C -- unbindService() -> MyService -- onUnbind() MyService -- onDestroy()
可以看出,
当一个
Service被创建-
onCreate()之后;如果任意组件想要销毁-
onDestroy()这个
Service;必须等到
Service与它关联的所有组件切断联系(通过
stopService()或者
unbindService())才行。
3.3 其它因素对生命周期的影响
对Service生命周期的影响还有其它的因素。
3.3.1 unbind()函数返回值
自定义Service时,
unbind()函数的返回值对
Service的生命周期是有影响的。它会决定
onRebind()函数是否被调用。
前面我们都看到了在
unbind()返回
false时
Service生命周期的变化。在
unbind()返回
true时,它的周期变化如下,
A -- startService() -> MyService -- onCreate() -> MyService -- onStartCommand() -> C -- bindService() -> MyService -- onBind() -> C -- onServiceConnected()被触发 -> C -- unbindService() -> MyService -- onUnbind() C -- bindService() -> MyService -- onRebind() -> C -- onServiceConnected()被触发 -> ......
也就是说,假如一个
Service正在运行,此时有个组件C要绑定它,那么会触发
onBind()函数;如果C解除绑定,然后又再次绑定,那么不会触发
onBind()而是触发
onRebind()函数。
3.3.2 bindService函数的参数
在绑定Service的时候,通常使用的
Context.BIND_AUTO_CREATE参数,
bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);
如果不使用
Context.BIND_AUTO_CREATE,那么一个
Service在没有被运行起来之前,使用
bindService()是不会让
Service自动运行起来的。
但是如果设置上了这个参数,那么就会让它运行起来,然后进行绑定。
除了
Context.BIND_AUTO_CREATE参数,还有好些参数可以使用,
BIND_NOT_FOREGROUND, BIND_ABOVE_CLIENT, BIND_ALLOW_OOM_MANAGEMENT, BIND_WAIVE_PRIORITY, BIND_IMPORTANT, BIND_ADJUST_WITH_ACTIVITY
可以用
|的方式同时使用其它的标志,例如,
bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE|Context.BIND_NOT_FOREGROUND);
3.3.3 onStartCommand函数返回值
前面的onStartCommand()返回值使用的是
START_STICKY,它对
Service的
onStartCommand()和周期都是有影响的。
Service启动之后,如果因为某种意外而停止运行(例如代码写的不好,
Service直接崩溃了),那么系统要自动的把这个
Service再运行起来。这个时候,
onStartCommand()的返回值就决定了
Service重启的行为,
START_STICKY:
Service重启(onCreate())之后,会触发
onStartCommand(),但是此时
onStartCommand()的参数
Intent会变成空值,
public class MyService extends Service { public MyService() { } ...... @Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent == null) { //因为这个Service在onStartCommand()返回的是START_STICKY,所以异常退出后,传入的`intent`是空值 } return START_STICKY; } }
START_NOT_STICKY:
Service将不会被自动重启,所以也就不会触发
onStartCommand();
START_REDELIVER_INTENT:
Service重启(onCreate())之后,会触发
onStartCommand(),此时
onStartCommand()的参数
Intent不会变成空值。该
Intent将是以前想要启动这个
Service的
Intent;如果以前有多个
Intent想要启动它,那么这里会传入最后一个,也就是最近的一个;
相关文章推荐
- STL之*min_element , *max_element ,*nth_element()[取容器中最大元素 最小元素 第n元素]
- 怎样在Eclipse中快速查看各种源代码?
- 【Spring4揭秘】修改Bean---BeanPostProcessor
- 鼠标双击
- myeclipse快捷键
- CountDownTimer 解决 Cancel无效的问题
- 转:java中时间戳各种实现方式获取效率
- 归并排序
- 深入Java集合:ArrayList实现原理
- 什么是编解码器codec
- 第十。十一周项目3 - 警察和厨师——1
- 希尔排序
- 关于gcc中string的sizeof
- 第15周程序阅读1
- 折半(二分)插入排序
- 常用命令
- 第十、十一周实践项目2 - 存储班长信息的学生类
- Apache Mina 入门实例
- Unity3d--摄像机视野远近的控制
- java 文件操作