Android开发--IntentService的用法,你错过了什么

IntentService是Android中提供的后台服务类,我们在外部组件中通过Intent向IntentService发送请求命令,之后IntentService逐个执行命令队列里的命令,接收到首个命令时,IntentService就开始启动并开始一条后台线程执行首个命令,接着队列里的命令将会被顺序执行,最后执行完队列的所有命令后,服务也随即停止并被销毁。

与Service的不同

  1. Service中的程序仍然运行于主线程中,而在IntentService中的程序运行在我们的异步后台线程中。在接触到IntentService之前,我在项目中大多是自己写一个Service,在Service中自己写一个后台线程去处理相关事务,而这些工作Android其实早已经帮我们封装的很好。
  2. 在Service中当我的后台服务执行完毕之后需要在外部组件中调用stopService方法销毁服务,而IntentService并不需要,它会在工作执行完毕后自动销毁。

IntentService的用法

1.编写自己的Service类继承IntentService,并重写其中的onHandleIntent(Intent)方法,该方法是IntentService的一个抽象方法,用来处理我们通过startService方法开启的服务,传入参数Intent就是开启服务的Intent。在这里我重写了一个MyService类去处理后台事务,每一次调用对count加1,并打印log。

package com.example.intentservicetest;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log; public class MyService extends IntentService { private static final String TAG = MyService.class.getSimpleName(); private int count = 0; public MyService() {
super(TAG);
// TODO Auto-generated constructor stub
} @Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
//在这里添加我们要执行的代码,Intent中可以保存我们所需的数据,
//每一次通过Intent发送的命令将被顺序执行
count ++;
Log.w(TAG, "count::" + count);
}
}

2.注册我们的服务:接下来在AndroidManifest文件中的Application标签下添加我们的服务。

<service android:name="com.example.intentservicetest.MyService" />
  • 1

3.在外部组件中开启服务:在这里我们在Activity中利用Intent循环10次开启服务。

for (int i = 0; i < 10; i++) {
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}

4.结果输出:

可以看到在MyService中是按照顺序执行我们的请求命令的。

原理分析

1.生命周期函数:
IntentService同样是继承于Service的,它也拥有相同的生命周期函数;

  • onCreate:服务创建时调用;
  • onStartCommand(Intent, int, int)方法:在Service源码可以看到onStart方法是在该方法中被调用的。每次组件通过startService方法启动服务时调用一次,两个int型参数,一个是组标识符,一个是启动ID,组标识符用来表示当前Intent发送是一次重新发送还是一次从没成功过的发送。每次调用onStartCommand方法时启动ID都不同,启动ID也用来区分不同的命令;
  • onDestroy方法:在服务停止时调用。

2.onCreate方法:首先让我们看看IntentService源码中的onCreate方法,

    @Override
public void onCreate() {
super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start(); mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}

可以看到:在IntentService的onCreate方法中开启了一个异步线程HandlerThread来处理我们的请求,并利用Looper和Handler来管理我们的请求命令队列。关于HandlerThread的用法可以参考以下博文:Android源码分析–Handler和Looper机制详解

3.如何停止服务
看到了onCreate方法我们就可以明白了,IntentService是如何开启异步线程以及如何管理命令队列的,那么我们之前曾提到:当后台服务处理结束后,我们并不需要再调用stopService方法销毁服务,IntentService会自动销毁,它是如何做到的呢?然我们看看ServiceHandler:

private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
} @Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}

在Handler中我们处理完每一个命令都会调用stopSelf(int)方法来停止服务:该方法需要来自onStartCommand方法中的启动ID,只有在接收到最新的启动ID时才会停止服务,就是说,我们的IntentService直到命令队列中的所有命令被执行完后才会停止服务。

setIntentRedelivery方法

在源码中我们可以发现,该方法改变了boolean变量mRedelivery的值,而mRedelivery得值关系到onStartCommand的返回变量:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

可以看到,mRedelivery不同,会返回两个不同的标志START_REDELIVER_INTENT 和START_NOT_STICKY,那么他们有什么不同呢?
区别就在于如果系统在服务完成之前关闭它,则两种类型就表现出不同了:

  • START_NOT_STICKY型服务会直接被关闭,而START_REDELIVER_INTENT 型服务会在可用资源不再吃紧的时候尝试再次启动服务。
  • 由此我们可以发现,当我们的操作不是十分重要的时候,我们可以选择START_NOT_STICKY,这也是IntentService的默认选项,当我们认为操作十分重要时,则应该选择START_REDELIVER_INTENT 型服务。

non-sticky服务和sticky服务

non-sticky服务会在自己认为任务完成时停止,若一个Service为non-sticky服务则应该在onStartCommand方法中返回START_REDELIVER_INTENT或START_NOT_STICKY标志。
sticky服务会持续存在,直到外部组件调用Context.stopService方法。sticky服务返回标志位START_STICKY。

注意:IntentService不应该处理长时间运行的服务(如音乐播放),长时间运行的服务应该由sticky服务完成。

Android开发--IntentService的用法,你错过了什么的更多相关文章

  1. Android开发中Bundle用法包裹数据(转)

    Android开发中Bundle用法包裹数据 Bundle的经典用法,包裹数据放入Intent中,目的在于传输数据. SDK 里是这样描述: A mapping from String values ...

  2. Android开发final的用法

    Android开发final的用法   final如果修饰类,该类不能被继承: final如果修饰变量,该变量不能被修改,不能再重新赋值,即变为常量: final如果修饰方法,该方法不能被重写: 此外 ...

  3. Android开发PreferenceActivity 用法的代码

    将开发过程中常用的一些内容做个收藏,下面资料是关于Android开发PreferenceActivity 用法的内容,希望对大伙有一些用处.public class Setting extends P ...

  4. Android学习总结(三)——IntentService的用法

    一.IntentService的基本概念 IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentServi ...

  5. Android开发学习清单

    目录: 第1章 Android应用与开发环境1.1 Android的发展和历史1.1.1 Android的发展和简介1.1.2 Android平台架构及特性1.2 搭建Android开发环境1.2.1 ...

  6. android 开发从入门到精通

    Android-Tips This is an awesome list of tips for android. If you are a beginner, this list will be t ...

  7. 【转】Android开发笔记(序)写在前面的目录

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

  8. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  9. Android开发初期之后怎么提升?怎么才能叫精通?方向在哪?

    hi大头鬼hi Android开发专家     先mark一下,好多人我发现始终停留在两三年的水平上没有突破. 另外还有一个误区就是越底层越牛逼 第三个就是,我认识的大部分所谓的做过rom开发的对fr ...

随机推荐

  1. windows系统开机执行文件

    以下都是在windows系统下执行的 开机自启程序 新建xxx.bat的文件 编辑自己的bat文件,将所要加载的项目引导进来 注意: 如果有相对路径的话,就需要先加载项目,在用python 执行脚本程 ...

  2. 《奋斗吧!菜鸟》 第九次作业:Beta冲刺 Scrum meeting 2

    项目 内容 这个作业属于哪个课程 任课教师链接 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11056511.html 团队名称 奋斗吧!菜鸟 作业学习目标 掌 ...

  3. (java)Jsoup爬虫学习--获取智联招聘(老网站)的全国java职位信息,爬取10页

    Jsoup爬虫学习--获取智联招聘(老网站)的全国java职位信息,爬取10页,输出 职位名称*****公司名称*****职位月薪*****工作地点*****发布日期 import java.io.I ...

  4. Eclipse的tab键为4个空格完整方法 附:阿里代码开发规范书

    开发规范书:http://pan.baidu.com/s/1dESdyox 1.点击 window->preference-,依次选择 General->Editors->Text ...

  5. stm32进入HardFault_Handler的定位方法

    写程序偶尔会遇到程序死机的现象.这个时候,就需要debug来定位. 通常情况下,程序会进入HardFault_Handler的死循环(针对stm32系列),我遇到过两次. 第一次是使用数组之前,数组的 ...

  6. django项目部署服务器后无法发送邮箱 错误信息:Connection unexpectedly closed

    使用配置: python 3.7 + django 2.2.1    发送邮件模块 :  from django.core.mail import send_mail 服务器:Centos7 阿里云轻 ...

  7. HDFS节点及原理

    HDFS节点角色: (1)namenode:1.用来存储HDFS的元数据信息,这里的元数据信息指的是文件系统的命名空间.启动时,将这些信息加载到namenode内存. 2.元数据信息也会在磁盘上保存成 ...

  8. SQL Server 默认跟踪(Default Trace)介绍使用

    背景 当数据库的表.存储过程经常别修改,当这些修改造成BUG的时候,很多开发都不承认是他们干的,那我们有没办法找出谁干的呢? SQL Server有Default Trace默认跟踪,数据库记录信息到 ...

  9. IDEA的安装和使用

    IDEA的特色功能 IDEA所提倡的是智能编码,是减少程序员的工作,IDEA的特色功能有以下22点 [1]  : ● 智能的选取 在很多时候我们要选取某个方法,或某个循环或想一步一步从一个变量到整个类 ...

  10. nginx优化、负载均衡、rewrite

    nginx优化 # 普通用户启动 (useradd nginx -s /sbin/nologin -M) user nginx; # 配置nginx worker进程个数 #worker_proces ...