2011-11-10 124 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。

我不知道你是否能服務綁定到自己,如果可以的話會很有趣......