Android:检查服务是否通过运行。装订服务

Android:检查服务是否通过运行。装订服务,android,service,state,Android,Service,State,检查Android服务是否正在运行的最佳方法是什么?我知道ActivityManagerAPI,但似乎不建议在与我类似的场景中使用该API()。我也知道使用全局/持久变量来维护服务状态的可能性 我曾尝试使用标志设置为0的bindService,但我遇到了与源链接上的人相同的问题(唯一的例外是,我尝试使用本地服务的bindService) 下面的电话 getApplicationContext().bindService(new Intent(getApplicationContext(),

检查Android服务是否正在运行的最佳方法是什么?我知道
ActivityManager
API,但似乎不建议在与我类似的场景中使用该API()。我也知道使用全局/持久变量来维护服务状态的可能性

我曾尝试使用标志设置为
0
bindService
,但我遇到了与源链接上的人相同的问题(唯一的例外是,我尝试使用本地服务的
bindService

下面的电话

getApplicationContext().bindService(new Intent(getApplicationContext(),
        MyService.class), mServiceConnection, 0);

始终返回true,但不连接。这是预期的行为吗?在我看来,
bindService
应该返回false,如果服务尚未运行(不是,我已经检查过了),或者如果没有设置
BIND\u AUTO\u CREATE
标志(同样,它没有设置)。

如果服务正在运行/未运行,您打算怎么做?为什么不直接调用
startService()
。如果没有运行,它将创建它,如果是,它将调用其onStart()方法。

我也有同样的需要,并发现运行.bindService时已经绑定了其他内容,这将导致错误。我在运行.bindService之前就这么做了

try{
    context.unbindService(fetch_connection);
} catch (IllegalArgumentException e){
    System.out.println("Unbinding didn't work. little surprise");
}

我也有同样的问题;似乎最著名的解决方案是在WhateverService中创建一个公共静态布尔值,在onCreate期间设置为true(或onStartCommand,由您选择),在onDestroy期间设置为false。然后,您可以从同一apk中的任何其他类访问它。不过,这可能很激烈。Android中没有API来检查服务是否正在运行(没有副作用):请参阅

我认为竞争条件来自这样一个事实,即操作系统可能随时终止远程服务(在另一个进程中)。如上所述,检查本地服务(同一进程)对我来说似乎没有竞争——如果操作系统终止服务,它也会终止检查其状态的任何内容。

请参阅此处的答案:


使用共享首选项保存服务运行标志

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int res = super.onStartCommand(intent, flags, startId);
    setRunning(true);
    return res;
}

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

private void setRunning(boolean running) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = pref.edit();

    editor.putBoolean(PREF_IS_RUNNING, running);
    editor.apply();
}

public static boolean isRunning(Context ctx) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
    return pref.getBoolean(PREF_IS_RUNNING, false);
}
另一种方法:

public static boolean isServiceRunning(Context ctx, String serviceClassName) {
    ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (TrackingService.class.getName().equals(serviceClassName)) {
            return true;
        }
    }
    return false;
}

在您的活动中,您可以通过使用您的服务实例简单地检查它 就我而言,我是用

  button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent=new Intent(MainActivity.this, MyService.class);
            //startService(intent);
            bindService(intent,serviceConnection,BIND_AUTO_CREATE);
            if (myService!=null)
            {
                myService.RecData(editText.getText().toString());
            }
        }
    });
}

ServiceConnection serviceConnection=new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        Toast.makeText(MainActivity.this,"onServiceConnected called",Toast.LENGTH_SHORT).show();
        MyService.MyBinder myBinder= (MyService.MyBinder) iBinder;
        myService= myBinder.getServiceInstant();
        myService.SetActivity(MainActivity.this);
        myService.RecData(editText.getText().toString());
    }

假设我想打印一条消息“服务正在运行”或“服务未运行”。这就是为什么我必须获得信息,如果服务正在运行或没有。我不能通过呼叫startService来做到这一点。但是为什么你要打印这条消息呢?如果服务没有运行,您只能做两件事。要么启动,要么不启动。因为我想通知用户服务是否正在运行。用户应手动启动和停止服务(通过按下按钮)。当用户关闭活动(后退按钮)时,服务应保持运行。当用户下次启动it时,活动应该知道服务已经在运行。我认为让用户知道服务通常是个坏主意。相反,让用户了解函数。如果由于未连接到服务而无法完成某项功能,请优雅地失败并通知用户。如果每次用户运行你的应用程序时,你都告诉他们一个服务正在运行,那会让人非常恼火。他们不关心服务是否正在运行,他们想要的只是功能。好吧,我看到我在这里没有提供足够的信息-我说活动将打印一条消息,只是说明在特定时间(活动开始时)需要什么类型的信息(服务是否在运行)。我并不是真的想关注可用性方面,因为其他应用程序正在使用类似的模式(例如android音乐播放器),而是关注如何做到这一点。因此,让我重新表述我的问题-android音乐播放器如何知道何时在活动开始时显示“播放按钮”(音乐播放器停止)以及何时显示“暂停按钮”(mp正在运行)?这只是检查您是否绑定到该服务。当我使用上面的代码时,它只提供运行服务的系统的信息。我正在寻找所有服务,包括我创建的服务。这不是一个好主意,SharedReferences会持久保存到非易失性存储中,因此,如果设备因某种原因崩溃或断电,则不会调用您的
onDestroy
,下次启动应用程序时,您会认为该服务正在运行,即使它没有运行。是的,我同意。SharedReference不适用于它。但是,运行pref的服务可以在应用程序启动时删除。另一种方法:在Application object.onDestroy中存储运行bool var的服务并不总是调用静态布尔值,因为如果用户关闭应用程序(例如:清除最近的应用程序)或设备意外关闭(例如:电池电量不足),共享首选项仍将为真。