当应用程序被杀害的Android后台服务正在重新启动(Android Background Serv

2019-07-21 19:08发布

我正在开发中创建一个后台服务来收集传感器数据的应用程序。 我开始从我的活动的服务:

startService(new Intent(this, MyService.class));

我创建了服务,所以如果应用程序被破坏,后台服务仍然继续收集数据。 我想这一点,和它的工作在一定程度上。 我的问题是,当我杀的应用,服务似乎重新启动,因为onCreate()服务和onStart()被调用的方法。 是否有与该服务没有重新启动,请什么办法?

更新:

正如下面的回答表明,我加入该服务,但没有运气下面的方法。

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

Answer 1:

这取决于onStartCommand返回的值。

你必须返回START_NOT_STICKY

根据该文件 :

对于启动的服务,也有操作的,他们可以决定在运行,这取决于他们从onStartCommand()返回值的两个附加的主要模式:START_STICKY用于显式启动和停止需要的服务,而START_NOT_STICKY或START_REDELIVER_INTENT使用一种新的服务应该只停留在处理发送给他们的任何命令运行

简而言之:如果返回START_STICKY只要资源可用的服务得到重建。 如果返回START_NOT_STICKY你不得不重新启动该服务发送一个新的意图。

由于所有的这引发了我的好奇,我做了一个样本应用程序来测试这一点。 你可以找到所有的拉链源这里有一个startService按钮和stopService按钮,你会期望从他们什么。 该服务在onStartCommand返回START_NOT_STICKY。 我把祝酒词中的onCreate,onStartCommand和的onDestroy。

这里发生了什么:

  • 如果我按下开始,和的onCreate都在onStart称为
  • 如果我按停,的onDestroy被触发
  • 如果我按两次启动,的onCreate被调用一次,两次onStartCommand

因此,它表现为人们所期望的。

如果我启动该服务,并为你描述终止该应用,的onDestroy不会被调用,但既不的onCreate或在onStart。

如果我能回到应用程序,我按下重新开始, 的onCreate被调用这意味着,正如我以前写的,START_NOT_STICKY防止服务得到自动重新启动。

我猜你有东西在你的其他应用程序启动再次服务(可能是悬而未决的意图)。



Answer 2:

该应用程序和服务生活在同一个过程中,当应用程序被杀害如此,你的服务,这意味着。 更改onStartCommand的返回值不会影响这一过程。 它简单地告诉服务时,你告诉它或要么启动/停止时,它的完成做什么,它需要。 正如您的评论中提到您原来的职位,将其设置为前台进程的工作,但实际上只是强迫服务对具有高优先级,而不是解决问题。

要改变这样,它的单独杀死了服务,并假设它是一个开始服务,而不是由于使用onStartCommand的绑定的服务,在清单为服务指定进程名称。

从进程和线程开发指南 :

对于每种类型的组件元素-的清单项< <activity>, <service>, <receiver>, and <provider> -支持一个机器人:可指定在其中该组件应运行的处理过程的属性。 使每个元件在其自身的进程运行或使一些组件共享一个进程,而别人没有,你可以设置该属性。 您还可以设置的android:工艺,使不同的应用程序的组件运行在相同的工艺,提供的应用程序共享相同的Linux用户ID和相同的证书签名。

Android的可能决定在某些时候关闭一个进程,当内存不足而需要通过更直接服务于用户的其他进程。 在这个过程中运行的真实杀死的应用组件因此被摧毁。 一个进程再次启动的时候再有工作给他们做这些组件。

<service>清单文件 :

机器人:过程

该过程,其中服务是运行的名称。 通常情况下,一个应用程序的所有组件在应用程序创建的默认进程中运行。 它具有相同的名称作为应用程序包。 元素的process属性可以为所有的组件不同的默认。 但组件可以用它自己的进程属性覆盖默认设置,允许你在多个进程展开你的应用程序。

(“:”)如果分配给该属性的名称以冒号开始,一个新的进程,私有的应用程序,在需要时创建和服务在该进程中运行。 如果进程名称以小写字母开头,该服务将在该名字的全局进程中运行,只要它具有这样的权限。 这使得在不同应用程序的组件共享一个进程,减少资源的使用。

不知道为什么会提到这是打倒对方答案投票。 我已经使用在过去和今天这种方法,创建了一个简单的活动应用对不同的工艺服务只是为了确保我是不是疯了。 我使用的Android设备监视器杀应用程序的过程。 您可以在ADM同时看到,独立的进程,可以看到,当应用程序的过程中被杀死,该服务的不是。



Answer 3:

开始不粘腻以上奇巧不工作,和其他onTaskRemoved上述MARSHMELLOW不工作。 onTaskRemoved可以通过处理一些例外情况使用。 没有工作这一点。 但尝试之一。



Answer 4:

如果您使用的是IntentService,它有一个

onHandleIntent() 

方法,你应该把需要执行的代码。 它是在一个单独的线程(不是您的应用程序运行的UI线程),因此您的应用程序不应该影响其执行。 当代码执行完毕,线程终止,该服务将自动停止。



Answer 5:

我知道它多晚来回答这个问题,但可能是它可以帮助他人。 这真的帮了我要我的音乐播放器应用程序。

如果有服务,这可能是破坏性的,也可以影响喜欢的音乐等方面的用户体验,那么在这种情况下,你必须使用通知,当服务启动成功,然后创建通知和使用功能

startForeground(int Notification_id,Notification);

这将在后台运行的服务,无需重新启动,并重新调用它的方法

https://developer.android.com/reference/android/app/Service.html



Answer 6:

当内存不足时,在后台运行的服务会自动就会被杀死。 除了使用startService()启动的服务,请尝试使用StartForeground()代替。 该服务在前台运行,甚至当存储空间不足将永远不会被杀死。



Answer 7:

我遇到了同样的问题,能够通过在全球进程中运行的服务来解决这个问题。 您可以通过添加下面的清单标签做到这一点:

过程= “com.myapp.ProcessName”

(化妆任何名称。)

当我这样做,我发现我的服务没有被杀(并重新启动)时,应用程序刷卡从列表中删除。 据推测,这是因为当你刷卡它关闭应用程序进程被终止,但全球服务流程都没有。

这样做的缺点是,你的应用程序和服务之间的通信,现在必须通过的IBinder接口; 你不能直接调用应用程序或服务功能从其他的一个,因为他们在不同的进程中运行。



文章来源: Android Background Service is restarting when application is killed