2011-11-10 88 views
2

如何跟踪“N”个任务 - 特别是当所有N个任务都完成并且任何任务失败时。Android - 跟踪IntentService中的多个操作

例如,我有一个服务可以响应5个独特的意图从远程服务器下载5个独特的数据。我还需要一次下载全部5个数据。与其重复下载数据的代码,不如启动5个Intents来下载所有数据,从而利用各个用例。

我有的问题是我需要知道什么时候所有5次下载尝试都已经完成。我无法跟踪服务中进行了哪些下载,因为我正在使用IntentService。 BroadcastReceivers也存在同样的问题,因为它们只存在onReceive方法的持续时间。

我在看sendOrderedBroadcast,但是这需要每次下载尝试都有一个BroadCastReceiver。我也有read结果是在发送完成时创建的,但不是因此在下载完成时会创建吗?

“如果resultReceiver参数为非空它指定一个 广播接收器,其的onReceive()的 发送有序广播意向完成当方法将被调用。”

也许我可以尝试使用sendOrederedBroadcast并在传递的Intent中封装某种计数器?

如果您要管理多个线程,使用线程池执行者,而不是也许能派上用场

回答

1

我有一个解决方案,是真的很整齐,没有出现打破任何Android范例。

概述 想象一下,IntentService响应六个动作。其中五项操作下载一些数据,第六项操作是一次性下载所有数据的请求。最初的问题是如何在响应下载所有项目的操作时重用逻辑来下载五个项目。还有一个要求,即在5次下载完成后收到通知。

当响应于动作来下载所有数据,将IntentService构造包含与每个下载动作的服务可以执行的意图字符串的ArrayList。 IntentService有效地调用自己传递下载的ArrayList来执行。每次服务执行下载时,都可以“弹出”ArrayList中的第一个条目,然后再次调用自己。

ArrayList不必包含所有5个下载,它可能是所有可用下载的子集!每一次下载尝试都可以启动任何意图传达个人成功或失败的意图,而不会中断下载“链”流或最终通知。最终只需要很少的代码来解决这个问题。

protected void onHandleIntent(Intent aIntent) { 
     String action = aIntent.getAction(); 
     // Data the service was called with. 
     Bundle incomingData = aIntent.getExtras(); 
     // Data used to launch any new Intents. 
     Bundle outgoingData = new Bundle(); 
     Intent result = null; 

     if (ACTION_DOWNLOAD_ALL.equals(action)) { 

       ArrayList<String> pendingDownloads = new ArrayList<String>(); 

       // This could contain any number of downloads, does not have to be all 5. 
       pendingDownloads.add(ACTION_DOWNLOAD_1);  
       pendingDownloads.add(ACTION_DOWNLOAD_2);   
       pendingDownloads.add(ACTION_DOWNLOAD_3); 
       pendingDownloads.add(ACTION_DOWNLOAD_4); 
       pendingDownloads.add(ACTION_DOWNLOAD_5); 

       // This will be the first download in the 'chain' to kick things off. 
       result = new Intent(pendingDownloads.get(0)); 

       // Add the list of downloads to the Intent 
       outgoingExtras.putStringArrayList("downloads", pendingDownloads); 
       result.putExtras(outgoingExtras); 

       // Start the download 'chain'. 
       startService(result); 

     } 
     else if (ACTION_DOWNLOAD_1.equals(action)) { 
      // ... Do download #1. 
      processDownloadChain(incomingData); 
     } 
     else if (ACTION_DOWNLOAD_2.equals(action)) { 
      // ... Do download #2. 
      processDownloadChain(incomingData);    
     } 
     else if (ACTION_DOWNLOAD_3.equals(action)) { 
      // ... Do download #3. 
      processDownloadChain(incomingData); 
     } 
     else if (ACTION_DOWNLOAD_4.equals(action)) { 
      // ... Do download #4. 
      processDownloadChain(incomingData); 
     } 
     else if (ACTION_DOWNLOAD_5.equals(action)) { 
      // ... Do download #5. 
      processDownloadChain(incomingData);    
     } 
} 

private void processDownloadChain(Bundle incomingData) { 

     if (incomingData != null) { 

      // Get the list of downloads. 
      ArrayList<String> downloads = incomingData 
        .getStringArrayList("downloads"); 

      if (downloads != null) { 

       // Remove the handled download request from the 'chain'. 
       downloads.remove(0); 

       if (downloads.size() > 0) { 
        // Have another download request to handle. 
        Intent result = new Intent(downloadIntents.get(0)); 
        Bundle outgoing = new Bundle(); 

        outgoing.putStringArrayList("downloads", downloads); 
        result.putExtras(outgoing); 
        startService(result); 
       } else { 
        // All downloads have been processed. 
        // Could notify BroadcastReceiver here. 
       } 
      } 
     } 
    } 

在私有方法processDownloadChain(...)是允许个人下载行为继续由IntentService即IntentService进行了空的检查仍然响应正常,下载操作。

0

开始每次下载请求开始结合,并解除绑定到一个新的异步任务的相同的服务本身在onExExcute/onPostExecute & onCancelled。

我不知道你是否能服务绑定到自己,如果可以的话会很有趣......