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. 技术分享:杂谈如何绕过WAF(Web应用防火墙)(转)

    0×01开场白 这个议题呢,主要是教大家一个思路,而不是把现成准备好的代码放给大家. 可能在大家眼中WAF(Web应用防火墙)就是"不要脸"的代名词.如果没有他,我们的" ...

  2. 让你的WPF程序在Win7下呈现Win8风格主题

    今天在Win8下使用了一个我之前写的一个WPF程序的时候,发现现在也支持Win8效果了(记得以前的.net 4.0的版本是不支持的).由于WPF的控件是自绘的,并不受系统主题所控制,也就是说.net ...

  3. Dell最近的几款显示器看上去还不错的样子

    发现最近戴尔最近发布了两款的4k显示器P2415Q和P2715Q,价格还比较平易近人,淘宝价24寸3700,27寸4700,让人有点心动了.基本参数如下: 3840*2160分辨率 亮度350cd/m ...

  4. 浅谈linux系统的分区问题

    转载:http://mtoou.info/linux-fenqu/ 很多然在装linux系统时面临的最大难题就是分区问题了,由于linux分区结构和windows不同,很多人对linux分区感觉非常不 ...

  5. android源码包下载

    http://rgruet.free.fr/public/ 其他下载地址:http://cid-b50f9d5897331c44.office.live.com/browse.aspx/Android ...

  6. Helm安装和项目使用

    整体架构 1.为什么要用? 首先在原来项目中都是基于yaml文件来进行部署发布的,而目前项目大部分微服务化或者模块化,会分成很多个组件来部署,每个组件可能对应一个deployment.yaml,一个s ...

  7. a<<=n

    a<<=n等价于a=a<<na<<n表示a左移n位(二进制)等价于a乘以2的n次方 a<<=n的含义就是,a等于a乘以2的n次方

  8. javat Itext实践 pdf

    1.简介 iText是著名的开放项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文件转化为PDF文件. 下载地址:https:/ ...

  9. sudo 添加

    sudo 添加 /etc/sudoers 找到root  ALL=(ALL)  ALL那一行, 复制之后,修改用户名:

  10. ​Mac触控板常用的手势操作

    ​Mac触控板常用的手势操作 学习了:http://topbook.cc/archives/151   一个手指直接点击,类似Windows中鼠标左键功能,同时在苹果Safari等浏览器中,这个手势还 ...