START_STICKY 和 START_NOT_STICKY
Posted
技术标签:
【中文标题】START_STICKY 和 START_NOT_STICKY【英文标题】:START_STICKY and START_NOT_STICKY 【发布时间】:2012-02-23 23:34:50 【问题描述】:在android中实现服务时START_STICKY
和START_NOT_STICKY
有什么区别?谁能指出一些标准的例子..?
【问题讨论】:
【参考方案1】:这两个代码仅在手机内存不足并在服务完成执行之前终止服务时才相关。 START_STICKY
告诉操作系统在它有足够的内存后重新创建服务,并以空意图再次调用 onStartCommand()
。 START_NOT_STICKY
告诉操作系统不要再费心重新创建服务。还有第三个代码START_REDELIVER_INTENT
,它告诉操作系统重新创建服务并将相同的意图重新传递给onStartCommand()
。
Dianne Hackborn 的这篇文章比官方文档更好地解释了这个背景。
来源:http://android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html
这里的关键部分是函数返回的新结果码, 如果它的进程告诉系统它应该如何处理服务 在运行时被杀死:
START_STICKY 与之前的行为基本相同,其中 服务保持“启动”状态,稍后将由系统重新启动。 与以前版本的平台的唯一区别是它 如果它因为进程被杀死而重新启动,onStartCommand() 将在具有 null Intent 的服务的下一个实例上调用 而不是根本不被调用。使用这种模式的服务应该 经常检查这种情况并妥善处理。
START_NOT_STICKY 表示,从 onStartCreated() 返回后,如果 该进程被终止,没有剩余的启动命令可以传递, 然后服务将停止而不是重新启动。这使得一个 对于仅在以下情况下运行的服务更有意义 执行发送给他们的命令。例如,可能会启动一个服务 每 15 分钟从警报开始轮询一些网络状态。如果得到 在做这项工作时被杀,最好让它成为 下一次警报响起时停止并开始。
START_REDELIVER_INTENT 类似于 START_NOT_STICKY,除非 服务的进程在它为给定的调用 stopSelf() 之前被杀死 意图,该意图将被重新传递给它,直到它完成 (除非经过多次尝试,它仍然无法完成,在 系统放弃哪一点)。这对于以下服务很有用 接受工作的命令,并希望确保他们做到 最终完成发送的每个命令的工作。
【讨论】:
如何避免重复调用任务handleStart(intent, startId);因为 onStart() 和 onStartCommand 都会被调用?这是一个好的设计吗? @弗兰克·利 什么是默认标志,如果没有指定? 如果按照“return super.onStartCommand(...);”您会看到,如果您的目标 sdk 版本默认低于 ECLAIR (API5=2.0),则返回 START_STICKY_COMPATIBILITY 并从 2.0 及更高版本返回 START_STICKY。START_NOT_STICKY
中的“没有剩余的启动命令”是什么意思?
@FrankLeigh 我不同意START_REDELIVER_INTENT
就像START_NOT_STICKY
。相反,它就像START_STICKY
【参考方案2】:
KISS回答
区别:
START_STICKY
系统会在你的服务被杀死后尝试重新创建它
START_NOT_STICKY
系统将不会在服务被终止后尝试重新创建服务
标准示例:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
return START_STICKY;
【讨论】:
这实际上并不正确且令人困惑。说:“服务被杀死”是错误的,因为人们可能认为您指的是 stopSelf 或 stopService,而您显然指的是进程被杀死。所以你最好在你的回答中使用文字过程。 嗨,我如何测试START_REDELIVER_INTENT
。我刚刚测试了START_STICKY
并通过最近的应用程序杀死了该应用程序。然后它召回服务。但是START_REDELIVER_INTENT
再也没有打过电话。为什么?
@IlyaGazman 我非常不同意。停止和杀死是两个截然不同的词。该答案以简单明了的方式正确解释了该问题。【参考方案3】:
START_STICKY
和 START_NOT_STICKY
的文档非常简单。
START_STICKY:
如果该服务的进程在启动时被杀死(之后 从
onStartCommand(Intent, int, int))
返回,然后将其留在 开始状态,但不保留此传递的意图。后来的 系统将尝试重新创建服务。因为它是在开始 状态,它会保证调用onStartCommand(Intent, int, int)
创建新服务实例后;如果没有任何待处理 启动要传递给服务的命令,它将被调用 一个空意图对象,所以你必须小心检查。此模式适用于将显式启动的事物,并且 停止运行任意时间段,例如服务 执行背景音乐播放。
示例:Local Service Sample
START_NOT_STICKY:
如果该服务的进程在启动时被杀死(之后 从
onStartCommand(Intent, int, int))
返回,没有 新的开始意图交付给它,然后将服务从 开始状态并且在未来明确调用之前不要重新创建Context.startService(Intent)
。该服务将不会收到onStartCommand(Intent, int, int)
调用null
Intent 因为 如果没有待交付的 Intent,则不会重新启动。这种模式对于想要做一些工作的事情很有意义 正在启动,但在内存压力下可以停止 稍后会明确地重新开始自己做更多的工作。一个例子 这种服务的一种是从服务器轮询数据:它 可以通过设置闹钟来安排闹钟每隔
N
分钟轮询一次 启动它的服务。当它的onStartCommand(Intent, int, int)
是 从闹钟中调用,它会在 N 分钟后安排一个新的闹钟, 并产生一个线程来进行联网。如果它的进程被杀死 在进行检查时,服务将不会重新启动,直到 闹钟响了。
示例:ServiceStartArguments.java
【讨论】:
不走运,伙计们。我无法用外行的话来联系文档。我想与实时场景相关。我想在设备上展示一个示例。让他们更容易理解。 对于 START_STICKY 和 START_NOT_STICKY onStartCommand() 将只执行一次并退出。我浏览了你指出的示例,但我怀疑 onStartCommand() 将执行多少次。如果我重新启动 START_STICKY 并且仍然尝试重新创建服务,那么服务会执行 onStartCommand 吗?? 重新创建服务时活动会发生什么?是否也重新创建了活动? 我想我们永远不会知道【参考方案4】:START_STICKY
:如果服务终止并且传递给onStartCommand()
方法的Intent数据是NULL
,它将重新启动服务。这适用于不执行命令但独立运行并等待作业的服务。
START_NOT_STICKY
:不会重启服务,对定期运行的服务很有用。仅当有待处理的startService()
调用时,服务才会重新启动。如果没有必要,最好避免运行服务。
START_REDELIVER_INTENT
:与STAR_STICKY
相同,它重新创建服务,调用onStartCommand()
并使用传递给服务的最后一个意图。
【讨论】:
以上是关于START_STICKY 和 START_NOT_STICKY的主要内容,如果未能解决你的问题,请参考以下文章