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

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


当前回答

这更适用于Intent Service调试,因为它们会生成一个线程,但也适用于常规服务。我找到这个线程感谢宾

在我的例子中,我摆弄了调试器并找到了线程视图。它看起来有点像微软Word里的项目符号图标。无论如何,您不必在调试器模式下使用它。单击该流程并单击该按钮。任何Intent服务都会在运行时显示出来,至少在模拟器上是这样。

其他回答

这更适用于Intent Service调试,因为它们会生成一个线程,但也适用于常规服务。我找到这个线程感谢宾

在我的例子中,我摆弄了调试器并找到了线程视图。它看起来有点像微软Word里的项目符号图标。无论如何,您不必在调试器模式下使用它。单击该流程并单击该按钮。任何Intent服务都会在运行时显示出来,至少在模拟器上是这样。

这是我提出的一个很好的解决方案,但它只适用于运行在单独进程中的服务。这可以通过在manifest中添加一个android:process属性来实现。

<service
        android:name=".ExampleService"
        android:process="com.example.service"
        ...

现在,您的服务将运行在具有给定名称的单独进程中。从你的应用程序你可以打电话

val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
activityManager.runningAppProcesses.any { it.processName == "com.example.service" }

如果服务正在运行,则返回true,否则返回false。

重要提示:请注意,它将显示您的服务是何时启动的,但当您禁用它时(即在系统从它解除绑定后),该进程仍然是活跃的。所以你可以简单地强制移除它:

override fun onUnbind(intent: Intent?): Boolean {
    stopSelf()
    return super.onUnbind(intent)
}

override fun onDestroy() {
    super.onDestroy()
    killProcess(Process.myPid())
}

然后它就完美地工作了。

onDestroy并不总是在服务中调用,所以这是无用的!

例如:只需要对Eclipse做一点更改就可以再次运行应用程序。使用SIG: 9强制退出应用程序。

检测服务是否正在运行的唯一有效/最快/干净的方法是创建PING/PONG功能。

在服务内部实现Messenger或AIDL方法:isAlive()——它返回服务的状态。

不要实现广播,因为它们可能被错过。

可以有多个具有相同类名的服务。

我刚刚创建了两个应用程序。第一个应用程序的包名是com.example.mock。我在应用程序中创建了一个名为lorem的子包和一个名为Mock2Service的服务。因此它的完全限定名是com.example.mock.lorem.Mock2Service。

然后我创建了第二个应用程序和一个名为Mock2Service的服务。第二个应用程序的包名是com.example.mock.lorem。服务的完全限定名是com.example.mock.lorem。Mock2Service。

这是我的logcat输出。

03-27 12:02:19.985: D/TAG(32155): Mock-01: com.example.mock.lorem.Mock2Service
03-27 12:02:33.755: D/TAG(32277): Mock-02: com.example.mock.lorem.Mock2Service

更好的方法是比较ComponentName实例,因为ComponentName的equals()比较包名和类名。一个设备上不能安装两个包名相同的应用程序。

ComponentName的equals()方法。

@Override
public boolean equals(Object obj) {
    try {
        if (obj != null) {
            ComponentName other = (ComponentName)obj;
            // Note: no null checks, because mPackage and mClass can
            // never be null.
            return mPackage.equals(other.mPackage)
                    && mClass.equals(other.mClass);
        }
    } catch (ClassCastException e) {
    }
    return false;
}

ComponentName