协慌网

登录 贡献 社区

如何检查服务是否在 Android 上运行?

如何检查后台服务(在 Android 上)是否正在运行?

我想要一个能够切换服务状态的 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;
}

我用它来称呼它:

isMyServiceRunning(MyService.class)

这是可靠的,因为它基于 Android 操作系统通过ActivityManager#getRunningServices提供的有关运行服务的信息。

使用 onDestroy 或 onSometing 事件或 Binders 或静态变量的所有方法都无法可靠地工作,因为作为开发人员,您永远不会知道,当 Android 决定终止您的进程或调用哪些回调时。请注意 Android 文档中生命周期事件表中的 “killable” 列。

不久前我遇到了同样的问题。因为我的服务是本地的,最后我简单地使用在服务类中的静态字段来切换状态,如 hackbod 描述这里

编辑(记录):

这是 hackbod 提出的解决方案:

如果您的客户端和服务器代码是同一个. apk 的一部分,并且您使用具体的 Intent(指定确切的服务类的那个)绑定到该服务,那么您可以简单地让您的服务在运行时设置一个全局变量你的客户可以检查。

我们故意没有 API 来检查服务是否正在运行,因为几乎没有失败,当你想要做类似的事情时,你最终会遇到代码中的竞争条件。

得到它了!

必须调用startService()来正确注册你的服务,并且传递BIND_AUTO_CREATE不够的。

Intent bindIntent = new Intent(this,ServiceTask.class);
startService(bindIntent);
bindService(bindIntent,mConnection,0);

现在是 ServiceTools 类:

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(String serviceClassName){
        final ActivityManager activityManager = (ActivityManager)Application.getContext().getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            if (runningServiceInfo.service.getClassName().equals(serviceClassName)){
                return true;
            }
        }
        return false;
     }
}