【发布时间】:2019-02-28 12:40:40
【问题描述】:
升级到 Android 8 后,我的应用程序的一些功能遭到破坏,甚至没有明确针对 API 26。特别是,检查服务是否正在运行的旧功能(如 StackOverflow 中所述:How to check if a service is running on Android?)不再起作用。
只是为了刷新我们的集体记忆,就是这个经典的方法:
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
现在的问题是 getRunningServices 现在已被弃用并且不再返回正在运行的服务。有人在 Android 8 上遇到过这个问题吗?
是否有任何官方解决方案(或黑客)可用?我还应该指出,我要查找的服务与调用isMyServiceRunning() 的代码在同一进程/应用程序中不(出于向后兼容性的原因,仍提供该功能) p>
【问题讨论】:
-
恕我直言,理想情况下,您的其他代码既不知道也不关心服务是否正在运行。我发现这个
isMyServiceRunning()有点代码味道。话虽这么说...如果此服务与调用isMyServiceRunning()的任何进程处于同一进程中,请使用staticboolean值,在onCreate()中设置并在onDestroy()中清除服务。检查boolean以查看服务是否正在运行。如果此服务在不同的进程中,并且您正在使用绑定模式,请绑定到不带BIND_AUTO_CREATE的服务。 -
@CommonsWare 我同意你对臭代码的看法。这里的问题是我需要用它来检查第三方应用程序的服务(它仍然是我的)。所以服务不与调用
isMyServiceRunning()的代码在同一个过程中,也许我应该在我的问题中指定它。 -
这是一位android架构师所说的:groups.google.com/forum/#!topic/android-developers/jEvXMWgbgzE
"We deliberately don't have an API to check whether a service is running because, nearly without fail, when you want to do something like that you end up with race conditions in your code." -
“这里的问题是我需要用它来检查第三方应用程序的服务”——你为什么关心服务是否正在运行?假设你的
isMyServiceRunning()返回true——你会做什么?假设它返回false——你会做什么? -
您不应依赖于服务的“物理”状态(已启动/未启动),而应依赖于其“逻辑”状态(例如已连接/未连接) - 您可以轻松检查该状态通过调用(无条件)
startService并通过Intent附加ResultReceiver或Messenger对象和内部Service#onStartCommand只需以当前状态响应
标签: java android android-8.0-oreo