与生命周期有关的方法

onCreate : 创建服务
onStart : 开始服务,Android2.0以下版本使用
onStartCommand : 开始服务,Android2.0及以上版本使用。该函数返回值为整型,一般取值START_STICKY,具体说明如下:
1、START_STICKY:粘性的服务。如果服务进程被杀掉,保留服务的状态为开始状态,但不保留传送的Intent对象。随后系统会尝试重新创建服务,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand方法。如果在此期间没有任何启动命令送给服务,那么参数Intent将为空值。
2、START_NOT_STICKY:非粘性的服务。使用这个返回值时,如果服务被异常杀掉,系统不会自动重启该服务。
3、START_REDELIVER_INTENT:重传Intent的服务。使用这个返回值时,如果服务被异常杀掉,系统会自动重启该服务,并传入Intent的原值。
4、START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被杀掉后一定能重启。
onDestroy : 销毁服务
onBind : 绑定服务
onRebind : 重新绑定。该方法只有当onUnbind返回true的时候才会被调用
onUnbind : 解除绑定。返回值true表示希望以后再绑定时能够调用onRebind方法,false表示再绑定时不调用onRebind方法

最简单的服务启动顺序:onCreate->onStartCommand
最简单的服务退出顺序:onDestroy

Service的生命周期流程

单独启停服务

启动服务,方法调用顺序为:onCreate->onStartCommand。日志如下:
01-06 17:25:14.309: D/FirstService(1604): onCreate
01-06 17:25:14.309: D/FirstService(1604): onStartCommand

停止服务,方法调用顺序为:onDestroy。日志如下:
01-06 17:25:30.485: D/FirstService(1604): onDestroy

已启动的服务再次启动,方法调用顺序为:onStartCommand。日志如下:
01-06 17:25:47.097: D/FirstService(1604): onStartCommand

单独绑定服务

直接绑定服务,方法调用顺序为:onCreate->onBind。日志如下:
01-07 09:13:12.521: D/FirstService(1360): onCreate
01-07 09:13:12.521: D/FirstService(1360): onBind

解绑服务,方法调用顺序为:onUnbind->onDestroy。日志如下:
01-07 09:13:31.905: D/FirstService(1360): onUnbind
01-07 09:13:31.905: D/FirstService(1360): onDestroy

先启动服务再绑定服务

启动服务,方法调用顺序为:onCreate->onStartCommand。日志如下:
01-07 10:47:53.685: D/FirstService(5486): onCreate
01-07 10:47:53.685: D/FirstService(5486): onStartCommand

接着绑定服务,方法调用顺序为:onBind。日志如下:
01-07 10:47:55.401: D/FirstService(5486): onBind

接着解绑服务,方法调用顺序为:onUnbind。日志如下:
01-07 10:47:59.565: D/FirstService(5486): onUnbind

接着再次绑定服务,方法调用顺序为:onRebind。日志如下:
01-07 10:48:03.109: D/FirstService(5486): onRebind

日志观察结果

从上面日志可以看出
1、在启动服务时,Android2.0及以上版本只调用onStartCommand方法,不调用onStart方法。
2、绑定服务时,只调用onBind方法或者onRebind方法,不调用onStart和onStartCommand方法。
3、通过startService启动服务后调用bindService绑定服务,此时解绑服务并不会销毁服务,解绑后再次绑定,调用的是onRebind方法而不是onBind方法。

Service的启停方式

外部启动和停止

类似Activity的启停,先声明一个Intent对象指定跳转的路径与数据,然后调用启动方法startService,停止则调用方法stopService。代码示例如下:
启动服务

     Intent mFirstIntent = new Intent(MainActivity.this, FirstService.class);startService(mFirstIntent);

停止服务

     stopService(mFirstIntent);

外部绑定和解绑

绑定前需要实现一个服务连接接口ServiceConnection,代码示例如下:

 private SecondService mSecondService;private ServiceConnection mConn = new ServiceConnection() {/** 获取服务对象时的操作 */public void onServiceConnected(ComponentName name, IBinder service) {mSecondService = ((SecondService.LocalBinder) service).getService();}/** 无法获取到服务对象时的操作 */public void onServiceDisconnected(ComponentName name) {mSecondService = null;}};

绑定服务

     Intent mSecondIntent = new Intent(MainActivity.this, SecondService.class);bindService(mSecondIntent, mConn, Context.BIND_AUTO_CREATE);

解绑服务

     if (mSecondService != null) {unbindService(mConn);mSecondService = null;}

Service内部启停

一般的服务停止可调用方法stopSelf(),不过Service实例因各种缘由常常会被系统杀掉(系统资源不足、服务挂起、用户退出Activity等等),像我们用手机听音乐,可不希望听一半就没声音了,所以这时我们要想办法保持播放音乐。startForeground便是这样一个方法,它在通知栏挂上服务的一条信息,从而让服务在前台运行,就不会被系统杀掉。startForeground方法可在onStartCommand中调用,对应的停止方法stopForeground可在onDestroy中调用,示例代码如下:

 @Overridepublic void onDestroy() {Log.d(TAG, "onDestroy");stopForeground(true);          //true表示清除通知,false表示不清除super.onDestroy();}@TargetApi(Build.VERSION_CODES.JELLY_BEAN)@Overridepublic int onStartCommand(Intent intent, int flags, int startid) {Log.d(TAG, "onStartCommand. flags="+flags);Intent actIntent = new Intent(this, MainActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(this,R.string.app_name,actIntent,PendingIntent.FLAG_UPDATE_CURRENT);Notification.Builder builder = new Notification.Builder(this);builder.setContentIntent(contentIntent).setSmallIcon(R.drawable.ic_launcher)            //设置状态栏里面的图标(小图标)).setTicker("前台运行")                         //设置状态栏的显示的信息.setWhen(System.currentTimeMillis())           //设置时间发生时间.setAutoCancel(true)                          //设置可以清除.setContentTitle("啦啦啦")                       //设置下拉列表里的标题.setContentText("我跑到前台,不怕被系统杀掉啦");//设置上下文内容Notification notify = builder.build();             //Android 4.1.2 及以上版本才支持该语句startForeground(1, notify);return START_STICKY;}

异步服务IntentService

Service虽然是后台服务,却跟Activity一样在主线程中,如果Service挂起,那么Activity页面也会死机。可是Service经常要做一些异步的操作,比如说网络访问请求等等,这样就不能拖累Activity。当然我们可以在Service中采取异步处理机制,比如说Thread+Handler等等,多写写代码都能实现。其实Android已经为我们考虑到了这种情况,所以提供了IntentService来处理。

IntentService是Service的子类,它通过Looper和Thread来解决Service中处理逻辑的阻塞问题。查看IntentService的源码,会发现其内部使用了线程HandlerThread,还使用了处理器ServiceHandler,相当于把Thread+Handler整套流程封装好了。具体需要异步操作的处理代码,我们直接重写onHandleIntent方法即可,确实是省了不少功夫。

使用IntentService与Service的代码区别如下:
1、新的服务类从继承Service改为继承IntentService;
2、增加一个构造方法,为的是给内部线程分配唯一名称,示例代码如下:

 private static final String TAG = "SecondService";public SecondService() {super(TAG);Log.d(TAG, "SecondService");}

3、重写onHandleIntent方法,把需要异步处理的代码写进去;
4、onStartCommand方法中记得调用父类的onStartCommand,因为Service类没有具体实现该方法但IntentService有具体实现,示例代码如下:

 @Overridepublic int onStartCommand(Intent intent, int flags, int startid) {Log.i(TAG, "onStartCommand threadname = " + Thread.currentThread().getName()); return super.onStartCommand(intent, flags, startid); }

点击下载本文用到的Service生命周期的工程代码

点此查看Android开发笔记的完整目录

Android开发笔记(四十一)Service的生命周期相关推荐

  1. Android开发笔记(十一)自定义视图的构造方法

    自定义视图的用法 Android自带的视图常常不能满足实际开发的需求,这种情况下我们就得自定义视图(View). 首先在res\values目录下找到attrs.xml(如没有则创建之),在该属性定义 ...

  2. 【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8523341 作者:毛星云(浅墨 ...

  3. 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 作者:毛星云(浅墨)    邮箱: happylifemxy@163.com 本篇文章里,我们首先对Direct3D之中固定功能流水线中的 ...

  4. 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩 纹理映射技术 二

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  5. Android开发笔记(序)写在前面的目录

    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入 ...

  6. Android开发笔记(序)

    本开发笔记,借鉴与其他开发者整理的文章范例与心得体会.在这里作为开发过程中的一个总结与笔记式记录. 如有侵犯作者权益,请及时联系告知删除.俗话说:集百家成一言,去粕成金. ************** ...

  7. Android开发笔记(序)写在前面的目录大全

    转自  湖前琴亭 的博客https://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面 ...

  8. Andriod开发之二十:Android开发笔记(序)写在前面的目录

    https://blog.csdn.net/aqi00/article/details/50038385 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教 ...

  9. Android开发笔记(四十二)Broadcast的生命周期

    Broadcast是什么 广播的特性 广播(Broadcast)用于Android组件之间的灵活通信,它与Activity和Service的区别在于: 1.Activity和Service都只能一对一 ...

最新文章

  1. BugKuCTF 加密 散乱的密文
  2. 常用 命令类,慢慢收集
  3. Myeclipse编辑器简单使用整理
  4. Spring Security中的SecurityContext和SecurityContextHolder是什么?
  5. codeforces 271A-C语言解题报告
  6. 教你彻底卸载Ubuntu双系统,去污不残留
  7. linux磁盘管理の进阶篇一
  8. 算法知识点——(3)监督学习——逻辑回归与线性回归
  9. 浅蓝色学校网站模板_学校网站源码_适用高中,中学,小学学校网站建设
  10. SPSS可信度数据分析
  11. python中的系统模块_python中与系统发育相关的模块
  12. 安卓电子书格式_在安卓上比较适合看英文电子书的软件
  13. 非接触IC卡读写模块MFRC530的工作原理及其应用
  14. 世界五大黑客:代码创造他们,他们改变世界!
  15. x y z 1 在python 中非法_Python面试考题
  16. 从启动过程讲述普元Mobile 8.0基座
  17. Bootstrap下拉菜单失效的解决方法+使用Bootstrap制作响应式网页
  18. RabbitMQ 开发时指定消息消费者的方式
  19. 58同成前端面试分析
  20. [ XJTUSE ]JAVA语言基础知识——2.2 Java基本数据类型

热门文章

  1. Linux入门(2)_给初学者的建议
  2. CSS垂直居中的七个方法
  3. android本地图片,Android中ImageView实现选择本地图片并显示功能
  4. element 方法返回的boolean被当成字符串了_quot;==quot;和 equals 方法有什么区别
  5. c语言判断输入类型是否为指定类型?
  6. JAVA正则提取字符串中的日期
  7. Windows 控制台cmd中文乱码的解决办法
  8. hbase集群 数据写入_HBase架构与原理详解
  9. matlab编写文件格式,MATLAB程序设计教程(4)——MATLAB文件操作
  10. ShardingSphere RAW JDBC 分布式事务 Narayana XA 代码示例