本篇的内容并不是介绍service使用方法和生命周期的,而是对其中的一些要点进行记录和分析。

我们都知道,Service是一个在后台执行的应用组件,用于在后台进行长期操作,例如进行网络事务,播放背景音乐等等。它又两种启动方式,如果其他的应用组件希望与该service进程内通信(IPC),可以通过与该service绑定来实现。关于生命周期的问题就不啰嗦了,直接放官档的图:

无论何种方式启动service,任何应用组件都可以使用该service。如果希望只有你自己的app才能使用该service,那么需要在manifest文件中加入android:exported属性,并将其设置为false。Android官方建议我们尽量使用显式的方式来启动service,从而保证app的安全。

另外,我们需要注意的是,在默认情况下service并不会重新开启一个独立的线程运行,而是运行于宿主进程的主线程中。显然,如果我们需要进行耗时操作,例如上面提到的播放背景音乐,网络操作等等,该如何解决?

    • 我们可以在activity中创建新线程,并在activity中对线程进行创建启动和销毁;
    • 使用asyncTask来完成任务;
    • 在service中新开一个线程来完成这些任务,以防ANR错误。

IntentService

当我们不需要同时处理多个请求的情况下,我们最好的解决方案是使用IntentService完成任务,而我们只需重写onHandleIntent()来完成处理逻辑即可。在IntentService进行了以下工作:

    • 新启动了一个worker线程来执行那些提交给onStartComand方法的intent任务。
    • 创建了一个work队列来存放多个请求任务,每次只向onHandleIntent()方法来传递一个intent来处理。
    • 当所有请求任务都完成后,则自动停止该service。
    • 默认的onStartCommand()方法中,将收到的intent参数传递给onHandleIntent()来处理。

下面是一个IntentService的示例:

public class HelloIntentService extends IntentService {

  /**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
} /**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
}
}

这里只需实现一个简单的构造函数和intent处理方法就可以了。当然,我们也可以根据需要重写service生命周期中的其他方法,但是请记得调用父类方法。我们需要清楚的是,所有提交给该service的任务都以intent的形式存放于一个队列中,IntentService里唯一的worker线程每次取一个intent来处理,都处理完后自动关闭IntentService。

如果希望多线程并发处理任务,那么需要继承service来处理任务了。这里就不演示具体代码了,但是有一点需要提醒一下。在onStartCommand方法会返回一个int值,通常我们返回父类的方法,这里的int值描述了当系统干掉service后的操作,它的几个常量选项如下:

    • START_NOT_STICKY : 当onStartCommand方法返回后,系统杀死了service,除非又有intent请求传递进来,否则将不会重新启动service。该选项可以很安全地确保当应用程序重启那些未完成的工作,而并不需要运行service时,避免service的启动运行。
    • START_STICKY: 当onStartCommand方法返回后,系统杀死了service,那么将会重新启动service,并执行onStartCommand方法,但是重新传递进来的intent并不是上一个intent了,而是使用null来代替(除非有新的intent请求)。该选项适用于类似于媒体播放器这种service,不执行任何命令,只是一直在运行等待任务。
    • START_REDELIVER_INTENT: 当onStartCommand方法返回后,系统杀死了service,那么将会重新启动service,并执行onStartCommand方法,重新传递进来的intent与上一个相同,随后而来的intent请求将会依次执行。该选项适用于类似下载任务的service,一直处于活跃状态,一旦挂掉就需要立即恢复。

另外,service还常常与notification相结合使用,使service可以运行到前台,例如音乐播放任务等等,可以与用户交互,这些内容以后再介绍。

Service不完全解析的更多相关文章

  1. Dubbo中@Service工作过程解析

    Dubbo中@Service工作过程解析 Spring中的BeanPostProcessor 首先我们应当了解到在spring体系中BeanPostProcessor是什么.加载流程 它是什么 Bea ...

  2. 微软BI 之SSIS 系列 - 在 SSIS 中使用 Web Service 以及 XML 解析

    开篇介绍 Web Service 的用途非常广几乎无处不在,像各大门户网站上的天气预报使用到的第三方 Web Service API,像手机客户端和服务器端的交互等都可以通过事先设计好的 Web Se ...

  3. C++请求web service与xml解析

    1. C++解析XML的开源库 在项目中XML的解析使用的是开源的第三方库,TinyXML:这个解析库的模型通过XML文件,然后再内存中生成DOM模型,从而让我们能够非常方便的遍历这颗XML树. DO ...

  4. 【应用服务 App Service】当遇见某些域名在Azure App Service中无法解析的错误,可以通过设置指定DNS解析服务器来解决

    问题情形 当访问部署在Azure App Service中的应用返回 "The remote name could not be resolved: ''xxxxxx.com'" ...

  5. Android组件系列----Android Service组件深入解析

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. 记录一起k8s的service服务名解析灵异事件

    故障现象: 基于alpine 3.7的镜像,构建的spring boot服务及eureka服务器. 在使用deployment和service文件部署到k8s集群之后, 在不同的pod内部,访问ser ...

  7. web service json 数组解析

     boolean workexpMark = true;     // 美发师工作经历json数组解析     org.json.JSONObject jsonObject = new org.j ...

  8. Android的init过程:init.rc解析流程

    这几天打算看下安卓的代码,看优秀的源代码也是一种学习过程,看源代码的过程就感觉到,安卓确实是深受linux内核的影响,不少数据结构的使用方法全然一致.花了一中午时间,研究了下init.rc解析过程,做 ...

  9. 用.NET WebService Studio调试Web Service解决SOAPAction的问题

    话说是这样的,这两天开发一个短信发送功能,客户给了一个 Web Service 地址(没有文档),让我调用就可以发送了, 我在VS 2013添加了服务引用,一切正常,可是执行代理方法时,怎么都报错 R ...

随机推荐

  1. 【sqli-labs】 less43 POST -Error based -String -Stacked with tiwst(POST型基于错误的堆叠变形字符型注入)

    和less42一样 login_user=&login_password=1');insert into users(id,username,password) value(15,'root' ...

  2. Java---23种设计模式(九)------组合模式

    一.什么是组合模式 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象. 组合模式依据树形结构来组合对象,用来表示部分以及整体层次. 这种类型的 ...

  3. SGU495Kids and Prizes 数学期望

    题意: 有n个奖品,m个人排队来选礼物,对于每个人,他打开的盒子,可能有礼物,也有可能已经被之前的人取走了,然后把盒子放回原处.为最后m个人取走礼物的期望. 题解: 本道题与之前的一些期望 DP 题目 ...

  4. vue组件的拆分

    vue组件的拆分 <div class="div"> <!-- 拆分出来的组件 自定义名字moban --> <moban></moban ...

  5. Django-xadmin+django-import-export导入导出的实现

    转载自:https://blog.csdn.net/zcyuefan/article/details/77748850 1. 需求vs现状1.1 需求要求做一个ERP后台辅助管理的程序,有以下几项基本 ...

  6. PAT 1080. Graduate Admission

    It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...

  7. 单元测试代码:SpringTest+JUnit

    /** * JUnit单元测试父类,配置了Spring的基础环境. <br/> * 可以作为Controller.Service.Dao单元测试的父类. * * @author leiwe ...

  8. netty自定义协议 心跳 断线重连源码

    https://github.com/aa1356889/NettyHeartbeat

  9. ACDream - k-GCD

    先上题目: B - k-GCD Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Sub ...

  10. [bzoj1070][SCOI2007]修车_费用流

    修车 bzoj-1070 SCOI-2007 题目大意:有m个人要修n台车,每个工人修不同的车的时间不同,问将所有的车都修完,最少需要花费的时间. 注释:$2\le m\le 9$,$1\le n \ ...