如何查看后台服务是否正在运行?
我想要一个切换服务状态的Android活动——它让我打开它,如果它是关闭的,如果它是关闭的。
如何查看后台服务是否正在运行?
我想要一个切换服务状态的Android活动——它让我打开它,如果它是关闭的,如果它是关闭的。
当前回答
摘自Android文档:
比如sendBroadcast(Intent),但是如果有任何接收器 这个函数将阻塞并立即分发它们 返回之前。
你可以把这次入侵看成是"ping "服务。因为我们可以同步广播,所以我们可以在UI线程上同步广播并获得结果。
服务
@Override
public void onCreate() {
LocalBroadcastManager
.getInstance(this)
.registerReceiver(new ServiceEchoReceiver(), new IntentFilter("ping"));
//do not forget to deregister the receiver when the service is destroyed to avoid
//any potential memory leaks
}
private class ServiceEchoReceiver extends BroadcastReceiver {
public void onReceive (Context context, Intent intent) {
LocalBroadcastManager
.getInstance(this)
.sendBroadcastSync(new Intent("pong"));
}
}
活动
bool serviceRunning = false;
protected void onCreate (Bundle savedInstanceState){
LocalBroadcastManager.getInstance(this).registerReceiver(pong, new IntentFilter("pong"));
LocalBroadcastManager.getInstance(this).sendBroadcastSync(new Intent("ping"));
if(!serviceRunning){
//run the service
}
}
private BroadcastReceiver pong = new BroadcastReceiver(){
public void onReceive (Context context, Intent intent) {
serviceRunning = true;
}
}
当然,在许多应用程序中,赢家是服务上的静态布尔字段,在service . oncreate()中设置为true,在service . ondestroy()中设置为false,因为它要简单得多。
其他回答
不久前我也遇到了同样的问题。由于我的服务是本地的,我最终只是在服务类中使用一个静态字段来切换状态,正如hackbod在这里描述的那样
编辑(供记录):
下面是hackbod提出的解决方案:
如果你的客户端和服务器代码是同一个.apk的一部分,而你是 绑定到服务的具体意图(一个指定 确切的服务类别),然后您可以简单地将您的服务设置为a 全局变量,当它正在运行时,您的客户端可以检查。 我们故意没有API来检查服务是否正确 跑步是因为,当你想做某事时,几乎没有失败 这样,代码中就会出现竞争条件。
在kotlin中,你可以在伴侣对象中添加布尔变量,并从任何你想要的类中检查它的值:
companion object{
var isRuning = false
}
在创建和销毁服务时更改它的值
override fun onCreate() {
super.onCreate()
isRuning = true
}
override fun onDestroy() {
super.onDestroy()
isRuning = false
}
摘自Android文档:
比如sendBroadcast(Intent),但是如果有任何接收器 这个函数将阻塞并立即分发它们 返回之前。
你可以把这次入侵看成是"ping "服务。因为我们可以同步广播,所以我们可以在UI线程上同步广播并获得结果。
服务
@Override
public void onCreate() {
LocalBroadcastManager
.getInstance(this)
.registerReceiver(new ServiceEchoReceiver(), new IntentFilter("ping"));
//do not forget to deregister the receiver when the service is destroyed to avoid
//any potential memory leaks
}
private class ServiceEchoReceiver extends BroadcastReceiver {
public void onReceive (Context context, Intent intent) {
LocalBroadcastManager
.getInstance(this)
.sendBroadcastSync(new Intent("pong"));
}
}
活动
bool serviceRunning = false;
protected void onCreate (Bundle savedInstanceState){
LocalBroadcastManager.getInstance(this).registerReceiver(pong, new IntentFilter("pong"));
LocalBroadcastManager.getInstance(this).sendBroadcastSync(new Intent("ping"));
if(!serviceRunning){
//run the service
}
}
private BroadcastReceiver pong = new BroadcastReceiver(){
public void onReceive (Context context, Intent intent) {
serviceRunning = true;
}
}
当然,在许多应用程序中,赢家是服务上的静态布尔字段,在service . oncreate()中设置为true,在service . ondestroy()中设置为false,因为它要简单得多。
这更适用于Intent Service调试,因为它们会生成一个线程,但也适用于常规服务。我找到这个线程感谢宾
在我的例子中,我摆弄了调试器并找到了线程视图。它看起来有点像微软Word里的项目符号图标。无论如何,您不必在调试器模式下使用它。单击该流程并单击该按钮。任何Intent服务都会在运行时显示出来,至少在模拟器上是这样。
检查服务是否正在运行的正确方法是简单地询问它。在您的服务中实现一个BroadcastReceiver来响应来自活动的ping。在服务启动时注册BroadcastReceiver,在服务被销毁时注销它。从您的活动(或任何组件)发送一个本地广播意图到服务,如果它响应,您就知道它正在运行。注意下面代码中ACTION_PING和ACTION_PONG之间的细微差别。
public class PingableService extends Service {
public static final String ACTION_PING = PingableService.class.getName() + ".PING";
public static final String ACTION_PONG = PingableService.class.getName() + ".PONG";
public int onStartCommand (Intent intent, int flags, int startId) {
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(ACTION_PING));
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy () {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
super.onDestroy();
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive (Context context, Intent intent) {
if (intent.getAction().equals(ACTION_PING)) {
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
manager.sendBroadcast(new Intent(ACTION_PONG));
}
}
};
}
public class MyActivity extends Activity {
private boolean isSvcRunning = false;
@Override
protected void onStart() {
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
manager.registerReceiver(mReceiver, new IntentFilter(PingableService.ACTION_PONG));
// the service will respond to this broadcast only if it's running
manager.sendBroadcast(new Intent(PingableService.ACTION_PING));
super.onStart();
}
@Override
protected void onStop() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
super.onStop();
}
protected BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive (Context context, Intent intent) {
// here you receive the response from the service
if (intent.getAction().equals(PingableService.ACTION_PONG)) {
isSvcRunning = true;
}
}
};
}