Service不完全解析
本篇的内容并不是介绍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不完全解析的更多相关文章
- Dubbo中@Service工作过程解析
Dubbo中@Service工作过程解析 Spring中的BeanPostProcessor 首先我们应当了解到在spring体系中BeanPostProcessor是什么.加载流程 它是什么 Bea ...
- 微软BI 之SSIS 系列 - 在 SSIS 中使用 Web Service 以及 XML 解析
开篇介绍 Web Service 的用途非常广几乎无处不在,像各大门户网站上的天气预报使用到的第三方 Web Service API,像手机客户端和服务器端的交互等都可以通过事先设计好的 Web Se ...
- C++请求web service与xml解析
1. C++解析XML的开源库 在项目中XML的解析使用的是开源的第三方库,TinyXML:这个解析库的模型通过XML文件,然后再内存中生成DOM模型,从而让我们能够非常方便的遍历这颗XML树. DO ...
- 【应用服务 App Service】当遇见某些域名在Azure App Service中无法解析的错误,可以通过设置指定DNS解析服务器来解决
问题情形 当访问部署在Azure App Service中的应用返回 "The remote name could not be resolved: ''xxxxxx.com'" ...
- Android组件系列----Android Service组件深入解析
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 记录一起k8s的service服务名解析灵异事件
故障现象: 基于alpine 3.7的镜像,构建的spring boot服务及eureka服务器. 在使用deployment和service文件部署到k8s集群之后, 在不同的pod内部,访问ser ...
- web service json 数组解析
boolean workexpMark = true; // 美发师工作经历json数组解析 org.json.JSONObject jsonObject = new org.j ...
- Android的init过程:init.rc解析流程
这几天打算看下安卓的代码,看优秀的源代码也是一种学习过程,看源代码的过程就感觉到,安卓确实是深受linux内核的影响,不少数据结构的使用方法全然一致.花了一中午时间,研究了下init.rc解析过程,做 ...
- 用.NET WebService Studio调试Web Service解决SOAPAction的问题
话说是这样的,这两天开发一个短信发送功能,客户给了一个 Web Service 地址(没有文档),让我调用就可以发送了, 我在VS 2013添加了服务引用,一切正常,可是执行代理方法时,怎么都报错 R ...
随机推荐
- 重新理解 Monad
对于大多数刚刚入门函数式编程的同学来说,monad(单子.又叫单体)可能是这里面的一道坎.你可能对 map . flatMap 以及 filter 再熟悉不过,可是到了高阶的抽象层次上就又会变得一脸懵 ...
- wx:for
.JSPage({ data: { input_data: [ { id: 1, unique: "unique1" }, { id: 2, unique: "uniqu ...
- Vue 爬坑之路—— 使用 Vuex + axios 发送请求
Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource 目前主流的 Vue 项目,都选择 axios ...
- 去掉二级页面 tabs 菜单, 修改返回按钮
imports: [ /*引入的模块 依赖的模块*/ BrowserModule, ComponentsModule, IonicModule.forRoot(MyApp,{ tabsHideOnSu ...
- springboot 大致启动流程
SpringApplication的run方法的实现是我们本次旅程的主要线路,该方法的主要流程大体可以归纳如下: 1) 如果我们使用的是SpringApplication的静态run方法,那么,这个方 ...
- day006 数字类型和字符串类型的内置方法
首先,为什么要有数据类型? 对于不同类型的变量,需要用不同的数据类型去描述. 数字类型的内置方法 数据类型又分为整形和浮点型.以下所述的内置方法均适用于这两个类型. 必须掌握的方法*** 数据类型有基 ...
- SpringBoot背景
1.SpringBoot的产生背景:随着spring日益发展,丰富的框架和组件大大简化了java项目开发过程,经过多年的实践,得到了很多人的认可,但是Spring的严重依赖XML配置文件,严重导致项目 ...
- 通过redis协议构建脏字过滤微服务
下载 https://github.com/jonnywang/... 安装使用 mkdir -p /data/server/wordsFilter cd /data/server/wordsFilt ...
- win安装配置Java8环境
这里就不重复造轮子,搜索一下. 一堆就出来 这里就引用一个百度知道的经验 https://jingyan.baidu.com/article/48b558e3f135687f38c09a03.html ...
- 15.Hibernate一对多双向关联映射+分页
1.创建如下数据库脚本 --创建用户信息表 --编号,用户名,密码,年龄,性别,昵称,手机,地址,管理员,图像地址 create table users ( id ) primary key, use ...