如何查看后台服务是否正在运行?
我想要一个切换服务状态的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事件或binder或静态变量的方法都不会可靠地工作,因为作为开发人员,你永远不知道Android何时决定杀死你的进程,或者调用哪些提到的回调。请注意Android文档中生命周期事件表中的“killable”列。
其他回答
一个小补语是:
我的目标是知道一个服务是否在运行,如果它没有运行。
调用bindService或调用一个可以被服务捕获的意图不是一个好主意,因为它会在服务未运行时启动服务。
因此,正如miracle2k所建议的,最好是在服务类中有一个静态字段,以知道服务是否已经启动。
为了使它更简洁,我建议用非常非常懒惰的抓取来转换单例中的服务:也就是说,通过静态方法完全没有实例化单例实例。service/singleton的静态getInstance方法只返回已经创建的单例实例。但它并不实际启动或实例化单例本身。服务只能通过正常的服务启动方法启动。
然后,修改单例设计模式,将令人困惑的getInstance方法重命名为类似isInstanceCreated(): boolean方法的方法会更加清晰。
代码如下所示:
public class MyService extends Service
{
private static MyService instance = null;
public static boolean isInstanceCreated() {
return instance != null;
}//met
@Override
public void onCreate()
{
instance = this;
....
}//met
@Override
public void onDestroy()
{
instance = null;
...
}//met
}//class
这个解决方案很优雅,但只有当你可以访问服务类时才有意义,而且只适用于服务的应用程序/包旁边的类。如果你的类在服务应用程序/包之外,那么你可以用Pieter-Jan Van Robays强调的限制来查询ActivityManager。
在serviceclass内部定义:
public static Boolean serviceRunning = false;
然后在onStartCommand(…)
public int onStartCommand(Intent intent, int flags, int startId) {
serviceRunning = true;
...
}
@Override
public void onDestroy()
{
serviceRunning = false;
}
然后,调用if(serviceclass。serviceRunning == true)。
检测服务是否正在运行的唯一有效/最快/干净的方法是创建PING/PONG功能。
在服务内部实现Messenger或AIDL方法:isAlive()——它返回服务的状态。
不要实现广播,因为它们可能被错过。
不久前我也遇到了同样的问题。由于我的服务是本地的,我最终只是在服务类中使用一个静态字段来切换状态,正如hackbod在这里描述的那样
编辑(供记录):
下面是hackbod提出的解决方案:
如果你的客户端和服务器代码是同一个.apk的一部分,而你是 绑定到服务的具体意图(一个指定 确切的服务类别),然后您可以简单地将您的服务设置为a 全局变量,当它正在运行时,您的客户端可以检查。 我们故意没有API来检查服务是否正确 跑步是因为,当你想做某事时,几乎没有失败 这样,代码中就会出现竞争条件。
Xamarin c#版本:
private bool isMyServiceRunning(System.Type cls)
{
ActivityManager manager = (ActivityManager)GetSystemService(Context.ActivityService);
foreach (var service in manager.GetRunningServices(int.MaxValue)) {
if (service.Service.ClassName.Equals(Java.Lang.Class.FromType(cls).CanonicalName)) {
return true;
}
}
return false;
}