Service stopSelf(int statId)和onStartcommand(Intent intent,int flags,int startId)
Stopping a service
A started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. So, the service must stop itself by calling stopSelf() or another component can stop it by calling stopService().
Once requested to stop with stopSelf() or stopService(), the system destroys the service as soon as possible.
However, if your service handles multiple requests to onStartCommand() concurrently, then you shouldn't stop the service when you're done processing a start request, because you might have since received a new start request (stopping at the end of the first request would terminate the second one). To avoid this problem, you can usestopSelf(int) to ensure that your request to stop the service is always based on the most recent start request. That is, when you call stopSelf(int), you pass the ID of the start request (the startId delivered toonStartCommand()) to which your stop request corresponds. Then if the service received a new start request before you were able to call stopSelf(int), then the ID will not match and the service will not stop.
上面是来自google官网的Service说明文档,大致意思是说:其一,用户必须自己管理Service的生命周期,其二,调用stopSelf(int)方法时,传入的startId和onStartcommand方法被回调时的startId应该相对应,这样就可以确保,当Service同时处理多个请求时,就不会因为第一个请求的结束后立即停止Service导致第二个请求没有被完全执行。上文红色字体标出stopSelf(int)方法结束Service时,会以最近的请求的startId为标准,也就是说,系统在回调stopSelf(startId)时,会用传入的startId和最近的请求的startId相比较,如果相同,则退出Service,否则,Service不会被停止。

如上图,水平方向上三个箭头,代表三个请求Service的任务,假设它们的执行时间都是一样的,进一步假设它们的startId分别为startId1、startId2和startId3。在T1时刻,Service接收到第一个请求,在T4时刻第一个请求已经被处理完毕,这时调用stopSelf(startId1),结束Service的生命周期时,发现最近请求的startId为startId3(T3时刻第三个请求到来了),所以T4时刻根本停不掉Service,同理T5时刻也停不调,直到T6时刻时,三个排队的任务都处理完了,才成功结束Service的生命周期。
所以综上,得到基本的结论:
- Service的stopSelf(int)方法被调用时不一定就能将自己的生命周期结束掉。
- onStartCommand方法由AMS通过消息回调,所以是顺序执行的,且在主线程中回调。
- AMS中保存一个ServiceRecord,其实它是一个binder token,可以跨进程传递代理对象到应用ActivityThread中,从而找到对应的Service对象。
Service stopSelf(int statId)和onStartcommand(Intent intent,int flags,int startId)的更多相关文章
- android startActivityForResult(Intent intent, int requestCode) 整理与总结! .
假设有两个Activity,主界面A,功能界面B,由A启动B,并传数据给B,B在经过处理后把数据传回给A. 先是A传B: Bundle bundle = new Bundle();bundle.put ...
- Android-----Intent通过startActivityForResult(Intent intent , int 标志符)启动新的Activity
我们都了解使用 startActivity(intent) 新的activity只能传递数据,却无法返回数据,返回新activity返回的数据我们可以替换startActivityForResult( ...
- Service 中的 onStart 和 onStartCommand
在自定义的service中,写了onStart和onStartCommand, public class HttpWebService extends Service { @Override publ ...
- Android-----Intent中通过startActivity(Intent intent )显式启动新的Activity
Intent:即意图,一般是用来启动新的Activity,按照启动方式分为两类:显式Intent 和 隐式Intent 显示Intent就是直接以“类名称”来指定要启动哪一个Activity:Inte ...
- Android-----Intent中通过startActivity(Intent intent )隐式启动新的Activity
显式Intent我已经简单使用过了,也介绍过概念,现在来说一说隐式Intent: 隐式Intent:就是只在Intent中设置要进行的动作,可以用setAction()和setData()来填入要执行 ...
- android:launchMode="singleTask" 与 onNewIntent(Intent intent) 的用法
最近项目开发中用到了android:launchMode="singleTask" 和 onNewIntent(Intent intent)两个特性,现总结一下经验: androi ...
- int a[5]={1,2,3,4,5}; int *p=(int*)(&a+1); printf("%d",*(p-1)); 答案为什么是5?
这个问题的关键是理解 &a a是一个数组名,也就是数组的首地址.对a进行取地址运算符,得到的是一个指向数组的指针!!!!这句话尤为重要!也就相当于int (*p) [5] = &a;p ...
- C++中将int转变成string和string转变成int
int to string #include<iostream> #include<string> using namespace std; int main() { stri ...
- HDU 3306 Another kind of Fibonacci(矩阵+ll超时必须用int&输入必须取模&M必须是int类型)
Another kind of Fibonacci [题目链接]Another kind of Fibonacci [题目类型]矩阵+ll超时必须用int&输入必须取模&M必须是int ...
随机推荐
- Redis源码解析之ziplist
Ziplist是用字符串来实现的双向链表,对于容量较小的键值对,为其创建一个结构复杂的哈希表太浪费内存,所以redis 创建了ziplist来存放这些键值对,这可以减少存放节点指针的空间,因此它被用来 ...
- 138.括号序列(区间型DP)
3657 括号序列 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 我们用以下规则定义一个合法的括号序列: ...
- trim()函数 mysql中的强大字符串过滤函数
mysql中功能强大的trim()函数. 去除两边空格: mysql> select trim(' hello world '); +-----------------------+ | tri ...
- Failed to Attach to Process ID Xcode 解决办法
方法1. go to the Product menu and find the Edit Scheme menu there. While in Edit Scheme window, select ...
- #iOS问题记录#UITableView加载后直接滑动倒最底部
类似QQ的聊天框,当进入聊天框,直接滑动倒最底部: 需要先将以他变了view滚动倒底部,再来移动NSIndexPath, 代码如下: -(void) doForceScrollToBottom { d ...
- MYSQL数据库迁移总结
Auth: JinDate: 2014-04-03 前端操作,后续测试对外开放不在本文 准备阶段操作阶段后续阶段 需求:phpcms和anquanzuo在一个mysql实例中anquanzuo有一张视 ...
- Promise小结
Promise是异步里面的一种解决方案,解决了回调嵌套的问题,es6将其进行了语言标准,同意了用法,提供了`promise`对象, promise对象有三种状态:pending(进行中) .Resol ...
- ylbtech-LanguageSamples-Delegates(委托)
ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Delegates(委托) 1.A,示例(Sample) 返回顶部 “委托”示例 本示例 ...
- dcm4che tools 之dicomdir
1.在dcm4che-3.3.7目录下的bin文件夹下运行命令行窗口 运行以下命令: dcmdir -c E:\TEMP\DICOMDIR E:\TEMP\04E439CE 为E:\TEMP\04E4 ...
- 理解JS里的稀疏数组与密集数组
一般来说,JavaScript中的数组是稀疏的. 什么是稀疏呢?稀疏也就是说,数组中的元素之间可以有空隙,因为一个数组其实就是一个键值映射.本文解释了如何创建稀疏数组和不稀疏的数组. 1.稀疏数组 创 ...