我有一个后台服务,有时候在内存不足时会被操作系统杀死。
- 如何模拟这种行为以便进行调试?
开发指南简单地说:“如果您的服务已启动,则必须设计它以通过系统的优雅重启来处理。如果系统杀死您的服务,它会在资源再次可用时立即重新启动它。”
- 当服务被杀死到完成重启时的调用顺序是什么?
另外一个相关的问题是,在服务被操作系统杀死时(即在服务.onDestroy被调用之前),在服务中启动的活动运行的AsyncTask会发生什么?它会继续运行还是与服务一起被静默地关闭?
我有一个后台服务,有时候在内存不足时会被操作系统杀死。
开发指南简单地说:“如果您的服务已启动,则必须设计它以通过系统的优雅重启来处理。如果系统杀死您的服务,它会在资源再次可用时立即重新启动它。”
另外一个相关的问题是,在服务被操作系统杀死时(即在服务.onDestroy被调用之前),在服务中启动的活动运行的AsyncTask会发生什么?它会继续运行还是与服务一起被静默地关闭?
onCreate()
接下来是...
int onStartCommand(Intent intent, int flags, int startid)
我知道在上面的评论中你提到了使用它,但值得重复的是:不要使用旧的"onStart()"事件。onStartCommand是新的做事方式。
onCreate()可以用来创建任何对象等,但实际上的服务代码应该放在onStartCommand()中。
完成onStartCommand()后,应返回结果。使用"START_STICKY"告诉操作系统如果需要杀死服务,则可以重新启动服务。使用"START_NOT_STICKY"告诉操作系统在内存再次可用之后不要再尝试重新启动服务。这意味着您的应用程序需要手动重新启动服务。还有其他选项-请查看API文档。
检查这些标志将使您能够看到为什么启动了您的服务-如果您自己的应用程序启动了它或者操作系统启动了它以重新启动它。您需要定期存储任何重要变量的状态,以便如果操作系统已经重新启动了它,您可以检索这些变量-您可以使用SharedPreferences私人存储来存储这些变量。一定要在onDestroy事件中存储任何变量,但不要指望该事件被调用。
此外,建议您将startID字段存储在一个变量中,并在服务运行结束时使用stopSelfResult(startId)。
请记住,如果操作系统杀死了您的服务,则可能没有机会存储任何变量。您需要能够在被操作系统重新启动时查看状态是否符合预期,如果不符合预期,则重置所有内容或者优雅地退出。
至于调试,您考虑编写另一个应用程序,在Activity中仅执行内存占用以强制发生低内存条件吗?顶部Activity应该优先使用内存并强制服务停止。
在服务中启动的其他线程仍然属于同一应用程序进程,因此它们将随着服务(和整个应用程序)一起被杀死。您可以通过在线程内添加常规日志语句,然后杀死服务来验证这一点。
还有一件对您有用的事情是从应用程序内部检查您的服务是否已经运行。下面是一个函数来实现这个功能:
// Determine if one of my services is currently running
public static boolean isMyServiceRunning(Context context, String servicename) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (servicename.equals(service.service.getClassName())) {
return true;
}
}
return false;
}
Tony Maro的答案的Kotlin版本:
@Suppress("DEPRECATION")
fun <T> Context.isServiceRunning(service: Class<T>): Boolean {
return (getSystemService(ACTIVITY_SERVICE) as ActivityManager)
.getRunningServices(Integer.MAX_VALUE)
.any { it.service.className == service.name }
}