当应用程序被终止时,Android后台服务正在重新启动
我正在开发一个应用程序,其中创build后台服务来收集传感器数据。 我从我的活动开始服务:
startService(new Intent(this, MyService.class));
我创build的服务,所以如果应用程序被销毁,后台服务仍然继续收集数据。 我尝试了这个,并在一定程度上起作用。 我的问题是,当我杀了应用程序,服务似乎重新启动,因为onCreate()
服务和onStart()
方法被调用。 请问有什么办法可以使服务不重启吗?
更新:
正如下面的答案中所build议的,我在服务中添加了以下方法,但没有运气。
@Override public int onStartCommand(Intent intent, int flags, int startId) { return START_NOT_STICKY; }
这取决于在onStartCommand中返回的值。
您必须返回START_NOT_STICKY
根据文件 :
对于已启动的服务,根据从onStartCommand()返回的值,他们可以决定运行两个额外的主要操作模式:START_STICKY用于根据需要显式启动和停止的服务,而使用START_NOT_STICKY或START_REDELIVER_INTENT对于在处理发送给它们的任何命令时应该只保持运行的服务
简而言之:如果您返回START_STICKY,则只要资源可用,服务就会重新创build。 如果您返回START_NOT_STICKY,则必须重新启动发送新意向的服务。
由于所有这些引发了我的好奇心,我做了一个示例应用程序来testing这个。 你可以在这里find所有源码的zip文件有一个startServicebutton和一个stopServicebutton,它们可以满足你对它们的期望。 服务在onStartCommand中返回START_NOT_STICKY。 我在onCreate,onStartCommand和onDestroy中放置敬酒。
这里发生了什么:
- 如果我按开始,onCreate和onStart被调用
- 如果我按停止,onDestroy被触发
- 如果我按两次启动,onCreate被调用一次,onStartCommand两次
所以它的行为如人们所期望的那样。
如果我按照上面所述启动服务并终止应用程序,则onDestroy不会被调用,但不会onCreate或onStart。
如果我回到应用程序,我再次按下开始, onCreate被调用 ,这意味着,正如我以前写的,START_NOT_STICKY防止服务自动重新启动。
我想你的应用程序中还有其他的东西可以再次启动服务(也许是一个未决的意图)。
应用程序和服务在同一个进程中生存,这意味着当应用程序被杀害,所以你的服务。 更改onStartCommand的返回值不会影响此过程。 它只是告诉服务,当你告诉它或者什么时候完成了它所需要的时候启动/停止。 正如您在原文中的评论中所提到的那样,将其设置为前台进程是有效的,但这只是强制服务具有高优先级,而不是解决问题。
要更改服务,以便单独终止服务,并且由于使用onStartCommand而假定服务是启动服务而不是绑定服务,请在该服务的清单中指定一个stream程名称。
从stream程和线程开发者指南 :
每个组件元素(
<activity>, <service>, <receiver>, and <provider>
的清单条目都支持一个android:process属性,该属性可以指定该组件运行的进程。 您可以设置此属性,以便每个组件在其自己的进程中运行,或者使某些组件共享一个进程,而另一些则不共享进程。 您还可以设置android:process,以便不同应用程序的组件在同一个进程中运行 – 只要这些应用程序共享相同的Linux用户标识并使用相同的证书进行签名。Android可能决定在某个时候closures某个进程,当内存不足时,其他进程会立即为用户提供服务。 在被杀死的进程中运行的应用程序组件因此被销毁。 当这些组件再次为他们工作时,将再次启动一个进程。
清单文件中的<service>
:
机器人:过程
服务要运行的进程的名称。 通常,应用程序的所有组件都在为应用程序创build的默认进程中运行。 它与应用程序包具有相同的名称。 元素的进程属性可以为所有组件设置不同的默认值。 但是组件可以使用自己的进程属性覆盖缺省值,从而允许将应用程序分布在多个进程中。
如果分配给该属性的名称以冒号(':')开始,则在需要时会创build一个专用于应用程序的新进程,并在该进程中运行该服务。 如果进程名称以小写字母开头,则该服务将以该名称的全局进程运行,前提是它有权这样做。 这允许不同应用程序中的组件共享一个进程,从而减less资源使用。
不知道为什么其他答案提到这是投票。 我过去曾经使用这种方法,今天创build了一个简单的Activity应用程序,在不同的进程中使用一个Service来确保我没有发疯。 我使用Android设备监视器来杀死应用程序的进程。 您可以在ADM中看到两个独立的进程,并可以看到,当应用程序的进程被终止时,服务不是。
如果你正在使用一个IntentService,它有一个
onHandleIntent()
方法,你应该放置需要执行的代码。 它是在一个单独的线程(不是你的应用程序运行的UI线程)执行的,因此你的应用程序不应该影响它。 代码执行完毕后,线程终止,服务自动停止。
我知道回答这个问题迟了很多,但可能对别人有帮助。 这真的帮助我的音乐播放器应用程序。
如果有服务可能是破坏性的,或者可能影响用户体验如音乐等,那么在这种情况下,您必须使用通知,并且当服务成功启动时,然后创build通知并使用function
startForeground(int Notification_id,Notification);
这将在后台运行您的服务,而无需重新启动并重新调用其方法
https://developer.android.com/reference/android/app/Service.html
开始不粘不上kitkat不工作,另一个onTaskRemoved不工作上面Marshmellow。 onTaskRemoved可以用于处理一些exception。 没有工作。 但是试试那个。
内存不足时,在后台运行的服务会自动被杀死。 而不是使用startService()启动服务,请尝试使用StartForeground()。 该服务在前台运行,即使内存不足也不会被杀死。
我遇到了同样的问题,并能够通过使服务在全局进程中运行来解决它。 您可以通过将以下内容添加到清单标记来完成此操作:
过程= “com.myapp.ProcessName”
(补上任何名字)
当我这样做时,我发现我的服务没有被杀害(并重新启动),当应用程序被从名单上删除。 据推测,这是因为应用程序进程在您刷卡时被终止,但全局服务进程不是。
这样做的缺点是你的应用程序和服务之间的通信现在必须通过IBinder接口; 您不能直接从另一个应用程序或服务中调用函数,因为它们运行在不同的进程中。