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的生命周期。

所以综上,得到基本的结论:

  1. Service的stopSelf(int)方法被调用时不一定就能将自己的生命周期结束掉。
  2. onStartCommand方法由AMS通过消息回调,所以是顺序执行的,且在主线程中回调。
  3. AMS中保存一个ServiceRecord,其实它是一个binder token,可以跨进程传递代理对象到应用ActivityThread中,从而找到对应的Service对象。

Service stopSelf(int statId)和onStartcommand(Intent intent,int flags,int startId)的更多相关文章

  1. android startActivityForResult(Intent intent, int requestCode) 整理与总结! .

    假设有两个Activity,主界面A,功能界面B,由A启动B,并传数据给B,B在经过处理后把数据传回给A. 先是A传B: Bundle bundle = new Bundle();bundle.put ...

  2. Android-----Intent通过startActivityForResult(Intent intent , int 标志符)启动新的Activity

    我们都了解使用 startActivity(intent) 新的activity只能传递数据,却无法返回数据,返回新activity返回的数据我们可以替换startActivityForResult( ...

  3. Service 中的 onStart 和 onStartCommand

    在自定义的service中,写了onStart和onStartCommand, public class HttpWebService extends Service { @Override publ ...

  4. Android-----Intent中通过startActivity(Intent intent )显式启动新的Activity

    Intent:即意图,一般是用来启动新的Activity,按照启动方式分为两类:显式Intent 和 隐式Intent 显示Intent就是直接以“类名称”来指定要启动哪一个Activity:Inte ...

  5. Android-----Intent中通过startActivity(Intent intent )隐式启动新的Activity

    显式Intent我已经简单使用过了,也介绍过概念,现在来说一说隐式Intent: 隐式Intent:就是只在Intent中设置要进行的动作,可以用setAction()和setData()来填入要执行 ...

  6. android:launchMode="singleTask" 与 onNewIntent(Intent intent) 的用法

    最近项目开发中用到了android:launchMode="singleTask" 和 onNewIntent(Intent intent)两个特性,现总结一下经验: androi ...

  7. 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 ...

  8. C++中将int转变成string和string转变成int

    int to string #include<iostream> #include<string> using namespace std; int main() { stri ...

  9. HDU 3306 Another kind of Fibonacci(矩阵+ll超时必须用int&输入必须取模&M必须是int类型)

    Another kind of Fibonacci [题目链接]Another kind of Fibonacci [题目类型]矩阵+ll超时必须用int&输入必须取模&M必须是int ...

随机推荐

  1. 【二分查找】POJ2456-Aggressive cows

    [题目大意] 有N间牛舍和M头牛,告诉你每个牛舍的位置,求出两头牛之间最小距离的最大值. [思路] 二分判断两头牛之间的最小距离d,通过贪心法进行验证. #include<iostream> ...

  2. bzoj 1712: [Usaco2007 China]Summing Sums 加密

    1712: [Usaco2007 China]Summing Sums 加密 Description     那N只可爱的奶牛刚刚学习了有关密码的许多算法,终于,她们创造出了属于奶牛的加密方法.由于她 ...

  3. uva10392 Factoring Large Numbers

    uva10392 Factoring Large Numbers 本文涉及的知识点是,使用线性筛选法得到素数表. Table of Contents 1 题目 2 思路 3 参考 1 题目 ===== ...

  4. 对js原型简单的理解和图解

    对js原型简单的理解和图解 最近在努力的学习js中,今天就抽了个空把自己理解的原型,记下一下在笔记中,以后自己查看,有空在会把原型链记录一下. 1.prototype prototype:是一个函数的 ...

  5. 利用cca进行fmri分析

    在肖柯的硕士毕业论文中<基于CCA的fMRI时空模型数据处理方法的研究>,他的总体思路是利用cca提取出fmri图像在时间和空间上两个相关系数,也就是两个特征,然后利用pca,对这两个特征 ...

  6. --secure-file-priv option so it cannot execute this statement

    MYSQL导入数据出现The MySQL server is running with the --secure-file-priv option so it cannot execute this ...

  7. Delphi 资源文件( .res)

    一.    现在的Windows应用程序几乎都使用图标.图片.光标.声音等,我们称它们为资源(Resource).最简单的使用资源的办法是把这些资源的源文件打入软件包,以方便程序需要的时候调用.资源是 ...

  8. OSG立体模式下动态修改相机远近裁剪面的实现

    1. 非立体模式下动态修改相机远近裁剪面 class GLB_DLLCLASS_EXPORT CGlbGlobeClipHandler : public osg::NodeCallback    { ...

  9. Intent传递对象的方法

    //传递对象 Bundle bundle = new Bundle(); intent = new Intent(getApplicationContext(), YourActivity.class ...

  10. 服务器提交了协议冲突. Section=ResponseHeader Detail=CR...的解决方案总结

    今天在HttpWebRequest发送一个网页请求的时候,HttpWebResponse返回了一个奇怪的错误信息: 这个Http协议请求类可是微软封装的,我使用的流程可是中规中矩,不可能是我写错代码, ...