START_STICKY和START_NOT_STICKY


Answers:


371

这两个代码仅在手机内存不足并在执行完成之前终止服务时才相关。 START_STICKY告诉操作系统在具有足够的内存后重新创建服务,onStartCommand()然后以空意图再次调用。START_NOT_STICKY告诉操作系统不要再重新创建服务。还有第三个代码START_REDELIVER_INTENT,告诉OS重新创建服务并将相同的意图重新传递给onStartCommand()

戴安娜·哈克伯恩(Dianne Hackborn)的这篇文章比官方文档更好地解释了其背景。

来源:http : //android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html

这里的关键部分是函数返回的新结果代码,告诉系统如果在运行过​​程中其进程被杀死,该服务应该如何处理:

START_STICKY与以前的行为基本相同,在该行为中,服务保持“启动”状态,稍后将由系统重新启动。与平台先前版本的唯一区别在于,如果由于平台进程被终止而重新启动平台,则将在服务的下一个实例中使用空Intent调用onStartCommand()而不是根本不调用它。使用此模式的服务应始终检查这种情况并进行适当处理。

START_NOT_STICKY说,从onStartCreated()返回后,如果进程被杀死且没有剩余的启动命令要传递,则该服务将停止而不是重新启动。对于只在执行发送给它们的命令时运行的服务而言,这更有意义。例如,可以每15分钟从警报启动一项服务以轮询某些网络状态。如果在执行此操作时将其杀死,最好只是将其停止并在下一次警报响起时启动。

START_REDELIVER_INTENT类似于START_NOT_STICKY,除了服务的进程在针对给定意图调用stopSelf()之前被杀死之前,该意图将重新交付给它直到完成为止(除非经过多次尝试仍无法完成,此时系统会放弃)。这对于正在接收要执行的工作命令的服务非常有用,并且希望确保它们最终确实完成了所发送的每个命令的工作。


1
如何避免重复调用任务handleStart(intent,startId); 因为onStart()和onStartCommand都将被调用?这是一个好的设计吗?@Frank Leigh
Sazzad Hissain Khan 2013年

2
但是,如果未指定默认标志,该怎么办?
IgorGanapolsky 2014年

3
如果您遵循“返回super.onStartCommand(...);” 您会看到,如果默认情况下目标sdk版本小于ECLAIR(API5 = 2.0),则会返回START_STICKY_COMPATIBILITY,而从2.0及更高版本返回START_STICKY。
MikeL 2014年

1
您在中“没有剩余的启动命令”是START_NOT_STICKY什么意思?
Malwinder Singh 2015年

3
@FrankLeigh我不同意START_REDELIVER_INTENT那样START_NOT_STICKY。相反,它就像START_STICKY
CopsOnRoad

107

答案

区别:

START_STICKY

系统被杀死后将尝试重新创建您的服务

START_NOT_STICKY

系统终止后将不会尝试重新创建服务


标准示例:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

5
这实际上是不正确和令人困惑的。这是一个错误的说法:“服务被杀死”是因为人们可能会认为您是指stopSelf或stopService,而您显然是指被杀死的进程。因此,您最好在答案中使用单词处理。
Ilya Gazman '16

嗨,我该如何测试START_REDELIVER_INTENT。我刚刚测试START_STICKY了最新的应用程序并杀死了该应用程序。然后召回服务。但是START_REDELIVER_INTENT再也没有打过电话。为什么?
阿西夫·穆斯塔克

@IlyaGazman我谨不同意。停止和杀死是两个完全不同的词。该答案以简单直接的方式正确地解释了该问题。
NoHarmDan

23

对于文档START_STICKYSTART_NOT_STICKY非常简单。

START_STICKY:

如果此服务的进程在启动时被杀死(从返回后onStartCommand(Intent, int, int)),则使其处于启动状态,但不要保留此传递的意图。稍后,系统将尝试重新创建该服务。因为它处于启动状态,它将确保onStartCommand(Intent, int, int) 在创建新的服务实例之后进行调用;如果没有任何待处理的启动命令要传递给该服务,则将使用空意图对象来调用它,因此您必须注意进行检查。

对于在任意时间段内将明确启动和停止运行的事物(例如执行背景音乐播放的服务),此模式有意义。

示例:本地服务样本

START_NOT_STICKY:

如果此服务的进程在启动时被杀死(从返回后onStartCommand(Intent, int, int)),并且没有新的启动意图要交付给它,则将该服务从启动状态中移除,直到以后对Context.startService(Intent)。的显式调用才重新创建 。不会收到onStartCommand(Intent, int, int)带有nullIntent 的呼叫,因为如果没有待发送的Intent可以传递,则不会重新启动该 呼叫。

对于希望由于启动而执行某些工作的事情来说,此模式是有意义的,但是可以在内存不足的情况下将其停止,并将稍后显式重新启动自己以执行更多工作。这种服务的一个示例是从服务器轮询数据的服务:它可以安排N警报启动警报服务,以每分钟轮询一次警报。当onStartCommand(Intent, int, int)从警报中调用它时,它将在N分钟后安排一个新警报,并产生一个线程进行网络连接。如果在执行该检查时杀死了它的进程,则直到警报响起,服务才会重新启动。

示例:ServiceStartArguments.java


没有运气的家伙..我无法用外行人的话来描述文件。我想谈一个实时场景。我想在设备上显示一个例子。以便他们更容易理解。
prago'2

START_STICKY和START_NOT_STICKY的onStartCommand()将仅执行一次并从中退出。我遍历了您所指出的示例,但是我怀疑将执行onStartCommand()多少次。如果我退出START_STICKY并仍然尝试重新创建服务,该服务将执行onStartCommand吗?
prago'2

重新创建服务后活动会怎样?活动也会重新创建吗?
ransh

我想我们永远不会知道
Denny
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.