检查Android服务是否正在运行的最佳方法是什么? 我知道ActivityManager API,但对于与我的(源)相似的场景,似乎不建议使用API。 我也意识到使用全局/持久变量维护服务状态的可能性。
我尝试将bindService与标志设置为0一起使用,但是我遇到了与源链接上的人相同的问题(唯一的例外是,我正在尝试使用本地服务的bindService)。
以下通话
getApplicationContext().bindService(new Intent(getApplicationContext(),
MyService.class), mServiceConnection, 0);
始终返回true,但未连接。 这是预期的行为吗? 在我看来,如果服务尚未运行(不是,我已经检查过)或未设置BIND_AUTO_CREATE标志(同样不是),则bindService应该返回false。
我有同样的问题;似乎最知名的解决方案是在WhateverService中创建一个公共的静态布尔值,在onCreate(或您选择的onStartCommand)期间设置为true,在onDestroy期间设置为false。然后,您可以从同一APK中的任何其他类访问它。虽然这可能是外在的。 Android中没有API可以检查服务是否正在运行(没有副作用):请参阅http://groups.google.com/group/android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d
我认为这种竞争状况是由于操作系统可能随时终止远程服务(在另一个进程中)而引起的。如上所述,检查本地服务(相同的过程)对我而言似乎是不争的事实-如果OS终止了该服务,那么它也将终止所有检查其状态的操作。
使用共享首选项保存服务运行标志。
@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);
}
这不是一个好主意,因为SharedPreferences会持久保存到非易失性存储中,所以如果由于某种原因设备崩溃或断电,则不会调用您的onDestroy,并且下次启动应用程序时,它会认为该服务正在运行不是。
是的我同意。 SharedPreferences不适用于此。但是,可以在应用启动时删除服务运行偏好。另一种方式:将运行bool var的服务存储在Application对象中。
onDestroy并不总是调用
最好保留一个静态布尔值,而不是静态布尔值,因为如果用户终止了该应用程序(例如清除最近的应用程序)或设备意外关闭(例如电池电量低),则共享首选项仍然为真。
另一种方法:
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;
}
当我使用上面的代码时,它仅提供系统运行服务的信息。我正在寻找所有服务,包括我创建的服务
我有同样的需求,发现运行.bindService与其他已经绑定的东西会导致错误。我在运行.bindService之前就这样做了
try{
context.unbindService(fetch_connection);
} catch (IllegalArgumentException e){
System.out.println("Unbinding didn't work. little surprise");
}
这只是检查您是否绑定到该服务。不管它是否开始。
在您的活动中,您只需使用服务实例即可对其进行检查
就我而言,我使用
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());
}
在这里查看答案:
如何检查服务是否在Android上运行?
如果服务正在运行/未运行,您打算怎么做?为什么不直接调用startService()。如果它没有运行,它将创建它,如果是,它将调用其onStart()方法。
假设我要打印一条消息"服务正在运行"或"服务未运行"。因此,无论服务是否运行,我都必须获取信息。我不能通过调用startService来做到这一点。
但是,为什么必须打印此消息?如果服务未运行,则只能执行2件事。是否启动它。
因为我想通知用户该服务是否正在运行。用户应手动启动和停止服务(通过按下按钮)。当用户关闭活动("后退"按钮)时,服务应保持运行状态。并且该活动应该知道,当用户下次启动它时,该服务已经在运行。
我认为让用户了解服务通常不是一个好主意。而是让用户知道功能。如果由于您未连接服务而无法完成某项功能,请优雅地失败并通知用户。如果您告诉用户每次他们运行您的应用程序时一项服务正在运行,那将非常烦人。他们不在乎服务是否正在运行,他们所需要的只是功能。
好的,我看到我在这里没有提供足够的信息-我说活动将打印一条消息,只是说明在特定时间(活动开始时)需要什么类型的信息(服务是否正在运行)。我并不是真的要专注于可用性方面,因为其他应用程序正在使用类似的模式(例如android音乐播放器),而是要如何做到这一点。因此,让我重新回答一下我的问题-android音乐播放器如何知道,何时在活动开始时显示播放按钮(音乐播放器已停止),何时显示暂停按钮(mp正在运行)?