安卓:如何确定 IntentService 是否在运行?

6

我有一个上传活动,其中我调用Intent服务。在那里,我处理API请求调用。

我想让一个活动知道服务是否正在运行,以显示上传标签。

我尝试了以下方法来确定服务是否正在运行:

public void startUploadServiceTask() {
    if (Util.isNetworkAvailable(mContext)) {

        if (!isMyServiceRunning(UploadDriveService.class)) {

                startService(new Intent(mContext,
                        UploadService.class));

            }
        } else {
            Toast.makeText(mContext,
                    "Service is already running.", Toast.LENGTH_SHORT)
                    .show();
        }
    } else {
        Toast.makeText(mContext,
                getString(R.string.please_check_internet_connection),
                Toast.LENGTH_SHORT).show();
    }
}



private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager
            .getRunningServices(Integer.MAX_VALUE)) {
        Log.e("ALL SERVICE", service.service.getClassName().toString());
        if (serviceClass.getName().equals(service.service.getClassName())) {

            return true;
        }
    }
    return false;
}

在“活动管理器运行服务信息”中,我无法获取正在运行的意图服务的类,因此这始终为false。
我已经使用广播来处理API调用的响应。
我甚至检查了这段代码。
if(startService(someIntent) != null) { 
 Toast.makeText(getBaseContext(), "Service is already running",     Toast.LENGTH_SHORT).show();
} else {
 Toast.makeText(getBaseContext(), "There is no service running, starting     service..", Toast.LENGTH_SHORT).show();
} 

但是在这段代码中,检查服务时它也会重新启动服务,因此服务被调用了两次。

请帮我解决这个问题。


尝试这个:https://dev59.com/KmMm5IYBdhLWcg3wdu5V#17591175 - Govind
1
这绝对是你想要的:https://dev59.com/mGs05IYBdhLWcg3wG-RR - Vektor88
2个回答

7

IntentService需要实现onHandleIntent()方法。该方法在工作线程上调用,以请求处理意图请求,并且只要处理一个意图请求,IntentService就会保持“活动状态”(我这里不考虑低内存和其他边缘情况,只是根据逻辑思考)。

当所有请求都被处理完毕后,IntentService会自行停止(因此您不应明确调用stopSelf())。

基于这个理论,您可以尝试以下逻辑:
在IntentService类内部声明一个类变量。
public static boolean isIntentServiceRunning = false;

@Override    
     protected void onHandleIntent(Intent workIntent) { 
        if(!isIntentServiceRunning) {
         isIntentServiceRunning = true;
       }
      //Your other code here for processing request
 }

在 IntentService 类的 onDestroy() 方法中,如果您愿意,可以设置 isIntentServiceRunning = false;

并使用 isIntentServiceRunning 来检查 IntentService 是否正在运行!


3
由于onDestroy()方法是在与onHandleIntent()不同的线程中调用的,因此这段代码不具备线程安全性。您应该使用synchronized()块来保护额外的代码。 - howettl
你如何从 Activity 中获取服务实例?这个问题使用了 ActivityManager,但是 Android 文档表示它只适用于测试和调试,所以这个解决方案不够好。https://developer.android.com/reference/android/app/ActivityManager.html - sergiomse

1
在您的代码中,您正在尝试从Activity获取服务的状态。正确的方法是服务应该提供状态。
活动与服务相互通信有几种可能性。由于您正在使用广播接收器,因此可以在服务启动时在onHandleIntent()方法中广播消息。
然后,在任务完成或出现任何错误的情况下,您可以再次调用广播接收器以获取服务完成事件。
这里有一个不错的教程link

如果服务已经启动,我转到另一个活动并返回上传活动,此时服务正在运行,但我无法获取任何响应,在问题中我已经写了我在示例中使用相同的代码。 - Ruchit Shah
在这种情况下,您可以在广播接收器中使用一个状态字段,并根据服务状态更改其值。每当您的活动获得焦点时,您都可以检查此值。 - Sandeep Solanki
@SandeepSolanki:您能否详细说明一下您对Ruchit Shah回复的解决方案?通常情况下,广播接收器是在Activity的onResume()方法中注册的,并在Activity的onPause()方法中取消注册。当广播接收器被取消注册时,如何为BroadcastReceiver分配一个值并在Activity中获取相同的状态字段(您所描述的)? - Tejas Sherdiwala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接