确定服务是否正在运行的正确方法

6

我正在我的应用中运行前台服务,我需要确定它们是否在我的活动中运行。

从我的搜索中,我发现这是一种选择:

private fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
    val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Int.MAX_VALUE)) {
        if (serviceClass.name == service.service.className) {
            return true
        }
    }
    return false
}

但是:

getRunningServices(Int):已弃用。

因此,我正在使用三种方式之一。

  1. 使用onResume将服务绑定到活动。 但我认为这对于仅检查服务是否正在运行的小事有些过度。
  2. 使Intent公开并检查其是否为空,但可能存在某些情况,其中Intent不为空但服务未运行。
  3. 检查前台服务持久通知是否处于活动状态,但这是一种解决方法。

检查服务是否正在运行的最正确的方法是什么?


这个回答解决了你的问题吗?Android - getRunningservices(ActivityManager)已被弃用 - emandt
答案是@SuppressWarnings("deprecation"),但这只是抑制警告的正确方式吗?我尽可能多地使用代码。getRunningServices可能会在几个月内完全被删除。 - Dim
你可以使用 bindService 并检查返回值,或者监听 ServiceConnection 回调来区分服务类型,尽管仍然可能存在一些问题。 - ininmm
3个回答

9
在Service本身中创建一个静态布尔值。 在onCreate中将其设置为true; 在onDestroy()中将其设置为false;
public class ActivityService extends Service {

public static  boolean IS_ACTIVITY_RUNNING = false;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    IS_ACTIVITY_RUNNING = true;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
            if(!IS_ACTIVITY_RUNNING)
                stopSelf();
    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    IS_ACTIVITY_RUNNING = false;
}}

现在,您可以通过布尔变量 ActivityService.IS_ACTIVITY_RUNNING 来检查您的活动是否正在运行。


2
在 Kotlin 中,这段代码对我来说是有效的 ->
@Suppress("DEPRECATION")
fun <T> Context.isServiceRunning(service: Class<T>): Boolean {
    return (getSystemService(ACTIVITY_SERVICE) as ActivityManager)
        .getRunningServices(Integer.MAX_VALUE)
        .any { it -> it.service.className == service.name }
}

接下来,您可以这样调用该函数 ->

context.isServiceRunning(MyService::class.java)

1
你可以在Service的onCreate方法中创建一个SharedPreferences,并在其中添加一些布尔值。
getSharedPreferences( getString( R.string.app_name ) , Context.MODE_PRIVATE )
     .edit()
     .putBoolean( getString( R.string.service_running_status_key ) , true )
     .apply()

同样地,在onDestroy方法中,将false附加到相同的键。然后,您可以使用SharedPreferences.getBoolean来检查Service是否在前台运行。

1
我不建议使用Shared Preferences来存储状态标志。如果应用程序由于某种原因崩溃,那么Shared Preference仍然会显示服务的错误状态。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接