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

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

  1. 同一个Service的onStartcommand方法是可以被调用者并发调用的,就是说同一个Service实例,它的onStartcommand方法可能同时执行多个请求处理(Inent)。
  2. Service的stopSelf(int)方法被调用时不一定就能将自己的生命周期结束掉。
时间: 2024-10-29 10:45:41

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

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

Intent:即意图,一般是用来启动新的Activity,按照启动方式分为两类:显式Intent 和 隐式Intent 显示Intent就是直接以“类名称”来指定要启动哪一个Activity:Intent intent = new Intent(this , activity.class); 其中activity.class就是要指定启动的activity 举个例子:新建有两个Activity:MainActivity 和 DemoActivity,现在从MainActivity跳转到DemoA

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

显式Intent我已经简单使用过了,也介绍过概念,现在来说一说隐式Intent: 隐式Intent:就是只在Intent中设置要进行的动作,可以用setAction()和setData()来填入要执行的动作和数据,然后再用startActivity()启动合适的程序. 此外:如果手机中有多个适合的程序,还会弹出列表供用户选择(假如你手机有两个浏览器,你打开一个连接,这是系统就会弹出两个浏览器列表供你选择) 在此举个使用隐式Intent打开activity的快速拨号例子: xml布局文件代码如下:

Activity.onNewIntent(Intent intent)的触发时机

Activity.onNewIntent(Intent intent)的触发时机和Activity的启动模式有关,所以先简单回顾一下"启动模式" Activity启动模式设置: <activity android:name=".MainActivity" android:launchMode="standard" /> Activity的四种启动模式: 1.standard 默认启动模式,每次激活Activity时都会创建Activi

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

int to string #include<iostream> #include<string> using namespace std; int main() { string s; char c[100]; int m=199; itoa(m,c,10); s=c; s.insert(0,"zhang"); cout<<s<<endl; return 0; } string to int #include<iostream&g

类模板相互引用的问题(错误:缺少类型说明符-假定为int。注意:C++不支持默认int)

问题描述: 现在有两个模板类(头文件A.h为1~14行,头文件B.h为15~27行): 1: /////////////////////////////////////////// 2: // file A.h 3: // 4: #include "B.h" 5: 6: template <class T> 7: class A 8: { 9: public: 10: T a; 11: B b_ptr; 12: A(): a(0), b_ptr(NULL) {} 13: }

int a[5]={1,2,3,4,5}; int *p=(int*)(&amp;a+1); printf(&quot;%d&quot;,*(p-1)); 答案为什么是5?

这个问题的关键是理解 &a a是一个数组名,也就是数组的首地址.对a进行取地址运算符,得到的是一个指向数组的指针!!!!这句话尤为重要!也就相当于int (*p) [5] = &a;p是一个指针,它指向的是一个包含5个int元素的数组!! 那么执行p+1后,p的偏移量相当于 p + sizeof(int) * 5 !! 而程序中强制将指针p转换成一个int* 那么 p -1 其实就是 p - sizeof(int)所以,p -1 指向了数组中得最后一个元素,也就是 5

android Intent的常用flags

首先,我们常见的由MainActivity跳转到另外一个Main1Acticity的代码: 1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 startActivity(mIntent); 一般的情况之下,以上两个Activity实例是放在task同一个栈里面.但是我们通过了解task的栈原理,知道每一个应用都有自己的task标志taskAffinity,不同的activity实例是可以在不同的栈里面运行

C#,int转成string,string转成int

转载:http://www.cnblogs.com/xshy3412/archive/2007/08/29/874362.html 1,int转成string用toString 或者Convert.toString()如下 例如:int varInt = 1; string varString = Convert.ToString(varInt); string varString2 = varInt.ToString(); 2,string转成int如果确定字符串中是可以转成数字的字符,可以用

【Java】Arrays中之于int数组的方法,Integer数组与int数组

在java.util.*中,Arrays似乎很有用的样子,似乎用里面的方法就可以避免使用for循环要自己写对数组的查找.初始化.排序等方法了. 一.先说说Arrays中对整形数组真的有用的方法 1.首先是Arrays.toString() 一般,直接用System.out.println()打印数组,比如这样: int array[] = { 8, 7, 100, 88, 6, 4, 5, 33, 10 }; System.out.println(array); 出来的结果是一堆乱码: [Lja