【问题标题】:How to check if a service is running on Android 8 (API 26)?如何检查服务是否在 Android 8 (API 26) 上运行?
【发布时间】: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() 的任何进程处于同一进程中,请使用static boolean 值,在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 附加 ResultReceiverMessenger 对象和内部 Service#onStartCommand 只需以当前状态响应

标签: java android android-8.0-oreo


【解决方案1】:

getRunningServices() 此方法不再可用于第三方应用程序。没有替代方法可以获取正在运行的服务。

https://developer.android.com/reference/android/app/ActivityManager.html#getRunningServices(int)

如何检查服务是否在 Android 上运行?) 我只是手动检查它,我在服务运行时将布尔值设置为 true,在服务停止或销毁时设置为 false。我正在使用 SharedPreferences 来保存布尔值。

服务类

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    Log.d("service", "onStartCommand")
    setRunning(true)
}

private fun setRunning(running: Boolean) {
    val sessionManager = SessionManager(this)
    sessionManager.isRunning = running
}


override fun onDestroy() {
   setRunning(false)
   super.onDestroy()
}

SessionManager.class

class SessionManager(var context: Context) {
    private val loginpreferences: SharedPreferences
    private val logineditor: SharedPreferences.Editor

    init {
      loginpreferences = context.getSharedPreferences(Pref_name, private_modde)
      logineditor = loginpreferences.edit()
    }

    var isRunning: Boolean
      get() = loginpreferences.getBoolean(SERVICES, false)
      set(value) {
         logineditor.putBoolean(SERVICES, value)
         logineditor.commit()
      }

    companion object {
      private val SERVICES = "service"
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    • 2011-05-25
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    相关资源
    最近更新 更多