如何查看后台服务是否正在运行?

我想要一个切换服务状态的Android活动——它让我打开它,如果它是关闭的,如果它是关闭的。


当前回答

不久前我也遇到了同样的问题。由于我的服务是本地的,我最终只是在服务类中使用一个静态字段来切换状态,正如hackbod在这里描述的那样

编辑(供记录):

下面是hackbod提出的解决方案:

如果你的客户端和服务器代码是同一个.apk的一部分,而你是 绑定到服务的具体意图(一个指定 确切的服务类别),然后您可以简单地将您的服务设置为a 全局变量,当它正在运行时,您的客户端可以检查。 我们故意没有API来检查服务是否正确 跑步是因为,当你想做某事时,几乎没有失败 这样,代码中就会出现竞争条件。

其他回答

对于kotlin,可以使用下面的代码。

fun isMyServiceRunning(calssObj: Class<SERVICE_CALL_NAME>): Boolean {
    val manager = requireActivity().getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (calssObj.getName().equals(service.service.getClassName())) {
            return true
        }
    }
    return false
}

下面是一个优雅的技巧,涵盖了所有的假设。这只适用于本地服务。

    public final class AService extends Service {

        private static AService mInstance = null;

        public static boolean isServiceCreated() {
            try {
                // If instance was not cleared but the service was destroyed an Exception will be thrown
                return mInstance != null && mInstance.ping();
            } catch (NullPointerException e) {
                // destroyed/not-started
                return false;
            }
        }

        /**
         * Simply returns true. If the service is still active, this method will be accessible.
         * @return
         */
        private boolean ping() {
            return true;
        }

        @Override
        public void onCreate() {
            mInstance = this;
        }

        @Override
        public void onDestroy() {
            mInstance = null;
        }
    }

然后是:

    if(AService.isServiceCreated()){
        ...
    }else{
        startService(...);
    }

在kotlin中,你可以在伴侣对象中添加布尔变量,并从任何你想要的类中检查它的值:

companion object{
     var isRuning = false

}

在创建和销毁服务时更改它的值

 override fun onCreate() {
        super.onCreate()
        isRuning = true
    }

override fun onDestroy() {
    super.onDestroy()
    isRuning = false
    }

同样,如果使用pending intent(例如使用AlarmManager),人们可能会发现另一种替代方法更干净:

public static boolean isRunning(Class<? extends Service> serviceClass) {
    final Intent intent = new Intent(context, serviceClass);
    return (PendingIntent.getService(context, CODE, intent, PendingIntent.FLAG_NO_CREATE) != null);
}

CODE是一个常量,您在类中私有地定义它,以标识与您的服务相关联的挂起意图。

得到它!

你必须调用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;
     }
}