更新时间 修改意见
2016-08-02 陈敏

第3节 Service的生命周期

3.1 Service的生命状态

Activity类似,Service也是有生命周期的。在实现一个Service的时候,可以覆盖它的生命周期函数,当它进入不同生命状态的时候,这些函数会被触发,我们就可以在它不同的生命阶段做不同的逻辑操作。

public class MyService extends Service {public MyService() {}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}@Overridepublic void onRebind(Intent intent) {super.onRebind(intent);}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}@Overridepublic 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. 情况1

    A -- startService() ->
    MyService -- onCreate() ->
    MyService -- onStartCommand() ->A -- stopService() ->
    MyService -- onDestroy()
  2. 情况2

    A -- startService() ->
    MyService -- onCreate() ->
    MyService -- onStartCommand() ->A -- startService() ->
    MyService -- onStartCommand() ->A -- stopService() ->
    MyService -- onDestroy()
  3. 情况3

    A -- startService() ->
    MyService -- onCreate() ->
    MyService -- onStartCommand() ->B -- startService() ->
    MyService -- onStartCommand() ->A -- stopService() ->
    MyService -- onDestroy()
  4. 情况4

    A -- startService() ->
    MyService -- onCreate() ->
    MyService -- onStartCommand() ->B -- startService() ->
    MyService -- onStartCommand() ->B -- stopService() ->
    MyService -- onDestroy()

可以看出,

  1. 任意组件调用startService()后,如果这个Service还没有创建,系统会首先创建-onCreate()

  2. 之后触发onStartCommand()

  3. 任意组件调用stopService()后,如果这个Service还没有被销毁,系统会销毁-onDestroy()

3.2.2 Bind Service的生命周期

onStartCommand()函数与onUnbind()函数也会对生命周期有影响,所以这里我们假设使用的是默认的返回值,

@Override
public boolean onUnbind(Intent intent) {//实际上是返回falsereturn super.onUnbind(intent);
}@Override
public int onStartCommand(Intent intent, int flags, int startId) {//实际上是返回START_STICKYreturn super.onStartCommand(intent, flags, startId);
}

组件触发Service运行的bindService()函数也会对生命周期有影响--第三个参数,所以这里我们假设使用Context.BIND_AUTO_CREATE

bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);

那么,对于只使用bindService()unbindService()来控制Service的情况:

  1. 情况1

    C -- bindService() ->
    MyService -- onCreate() ->
    MyService -- onBind() ->
    C -- onServiceConnected()被触发 ->C -- unbindService() ->
    MyService -- onUnbind()
    MyService -- onDestroy()
  2. 情况2

    C -- bindService() ->
    MyService -- onCreate() ->
    MyService -- onBind() ->
    C -- onServiceConnected()被触发 ->C -- bindService() ->
    MyService -- 无变化C -- unbindService() ->
    MyService -- onUnbind()
    MyService -- onDestroy()
  3. 情况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. 情况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()

可以看出,

  1. 任意组件调用bindService()后,如果这个Service还没有创建,系统会首先创建-onCreate()

  2. 之后触发onBind()

  3. 之后组件的onServiceConnected()被触发,告知绑定成功;

  4. 任意已绑定的组件调用unbindService()后,会触发onUnbind()

  5. 如果这个Service没有与其他的组件绑定,那么系统会销毁-onDestroy()

3.2.3 混合模式下的生命周期

对于使用了startService() stopService()bindService()unbindService()等两种方式来控制Service的情况:

  1. 情况1

    A -- startService() ->
    MyService -- onCreate() ->
    MyService -- onStartCommand() ->C -- bindService() ->
    MyService -- onBind() ->
    C -- onServiceConnected()被触发 ->C -- unbindService() ->
    MyService -- onUnbind()A -- stopService() ->
    MyService -- onDestroy()
  2. 情况2

    A -- startService() ->
    MyService -- onCreate() ->
    MyService -- onStartCommand() ->C -- bindService() ->
    MyService -- onBind() ->
    C -- onServiceConnected()被触发 ->A -- stopService() ->
    MyService -- 无变化C -- unbindService() ->
    MyService -- onUnbind()
    MyService -- onDestroy()
  3. 情况3

    C -- bindService() ->
    MyService -- onCreate() ->
    MyService -- onBind() ->
    C -- onServiceConnected()被触发 ->A -- startService() ->
    MyService -- onStartCommand() ->C -- unbindService() ->
    MyService -- onUnbind()A -- stopService() ->
    MyService -- onDestroy()
  4. 情况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()返回falseService生命周期的变化。在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的周期都是有影响的。

Service启动之后,如果因为某种意外而停止运行(例如系统回收了该Service),那么系统要自动的把这个Service再运行起来。这个时候,onStartCommand()的返回值就决定了Service重启的行为,

  1. START_STICKYService重启(onCreate())之后,会触发onStartCommand(),但是此时onStartCommand()的传入的参数Intent会变成空值,

    public class MyService extends Service {public MyService() {}......@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {if(intent == null) {//因为这个Service在onStartCommand()返回的是START_STICKY,所以异常退出后,传入的`intent`是空值}return START_STICKY;}
    }
  2. START_NOT_STICKYService将不会被自动重启,所以也就不会触发onStartCommand()

  3. START_REDELIVER_INTENTService重启(onCreate())之后,会触发onStartCommand(),此时onStartCommand()的参数Intent不会变成空值。该Intent将是以前想要启动这个ServiceIntent;如果以前有多个Intent想要启动它,那么这里会传入最后一个,也就是最近的一个;


/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。

*另外,我们还推出了Arduino智能硬件相关的教程,您可以在我们的网店跟我学Arduino编程中购买相关硬件。同时也感谢大家对我们这些码农的支持。

*最后再次感谢各位读者对安豆的支持,谢谢:)
/*******************************************************************/

四大组件之Service(二)-Service在各种情况下的生命周期相关推荐

  1. Android实训课程之三 这次课老师先是提到了Android有四大组件:Activity、Service、Broadcast Receiver、Content Provider。然后重点提到Acti

    Android实训课程之三 这次课老师先是提到了Android有四大组件:Activity.Service.BroadcastReceiver.ContentProvider.然后重点提到Activi ...

  2. Android基础再回首——四大组件之Activity、Service俩兄弟

    Android基础再回首--四大组件之Activity.Service俩兄弟 偶尔的回首过去,总是有不一样的收获.今天就来回顾下Activity和service吧,不用嫌弃太基础了,打好基础是取得成功 ...

  3. .net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制

    .net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制一.控件生命周期 先回述上篇,可能表述没有不清晰,也可能跨度大了点,好的,我们来一个循序渐进过程,大家都知道,武术都有招术的,先出什 ...

  4. 【实习小tip】多层dialog弹窗遮罩问题、elementUI的form表单组件的select框在只读的情况下没办法拿到传来的数据、从弹窗子组件获取数据后需要刷新页面

    解决elementui多层dialog弹窗遮罩问题 弹窗套娃出现了整个屏幕都是遮罩层的问题,需要鼠标点击一下才能正常. 在弹窗组件代码上加上 append-to-body 就可以了,表示这个弹窗是嵌在 ...

  5. 安卓基础巩固(二):四大组件:Activity、Service、Broadcast、Content Provider

    文章目录 Activity 生命周期 onCreate和onStart的区别 onPause和onStop的区别 生命周期的变化 Activity的启动 Intent Bundle Activity携 ...

  6. Android四大组件之一服务(Service)

    Service(服务): 1. Android的四大组件之一,存在自己的生命周期 2. 一种可以在后台执行长时间运行操作而没有用户界面的应用组件,需要在AndroidManifest.xml配置相关信 ...

  7. Android 编程下的四大组件之服务(Service)

    服务(Service) 是一种在后台运行,没有界面的组件,由其他组件调用开始.Android 中的服务和 Windows 中的服务是类似的东西,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类 ...

  8. Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口...

    Service Service的奇妙之处.在于他不须要界面,一切的操作都在后台操作,所以非常多全局性(手机助手,语音助手)之类的应用非常长须要这个.我们今天也来玩玩 我们新建一个project--Se ...

  9. android同步服务启动,Android Service的基本用法(startService启动方式生命周期)

    概念:Service作为安卓的四大组件之一,并不像Activity一样,能够被我们看到.通常,它用于在后台为我们执行一些耗时,或者需要长时间执行的一些操作的.(可理解为没有界面的Activity) 使 ...

最新文章

  1. java plc通讯_树莓派+西门子PLC+Aliyun
  2. 《剑指offer》c++版本 7.重建二叉树
  3. java 加减运算_JAVA日期加减运算 | 学步园
  4. 电子计算机 俗称 它是一种具有,2013年计算机一级B试题模拟1
  5. 属性拼接转换成字符串_使用一些可选的将字符串配置属性转换为其他类型
  6. c++折线平移算法_RSA笔记-蒙哥马利算法(1)
  7. Json的反序列化 .net Newtonsoft.Json
  8. oracle 视图及函数授权,Oracle常见1000问之内部函数及管理视图
  9. 电信用户流失预测Telco customer churn—(基于逻辑回归)
  10. uniapp 安卓/ios 录音授权,录制音频,录音文件上传
  11. 手动实现一维离散数据小波分解与重构
  12. ArcGIS 10.4 Desktop安装步骤。
  13. 解决w950播放RM视频的问题[转]
  14. 带你初步了解药物设计中的生物信息学
  15. 破除谷歌浏览器Google Chrome启动时打开hao123,2345等流氓网页
  16. (转)Android Jetpack Compose 最全上手指南
  17. NLP基本功-文本相似度 | AI产品经理需要了解的AI技术通识
  18. 开启dubbo之旅——Dubbo Admin(新版)
  19. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java实验室预约管理系统5x7en
  20. RSA加密、解密、签名、验签介绍

热门文章

  1. css 流式布局 九宫格布局
  2. android.mk 执行脚本,Android.mk的用法
  3. 常用的iPhone app快捷url链接
  4. 利用HTTP协议获取163的联系人列表(2)
  5. React Redux 与胖虎他妈
  6. 通过域 组策略禁用U盘(只允许部份许可U盘可在客户端读取)
  7. CureApp入选世界经济论坛技术先锋
  8. 西门子vav控制器_西门子电子式房间温控器用于VAV和CAV系统RCU50、RCU50.1、RCU50.2...
  9. 网银支付处理 | 京东支付处理
  10. 【2022高教社杯数学建模】C题:古代玻璃制品的成分分析与鉴别方案及代码实现(已经更新完毕)