如何跟踪“N”个任务 - 特别是当所有N个任务完成且任务失败时。
例如,我有一个服务可以响应5个独特的Intents从远程服务器下载5个独特的数据。我还要求一次下载所有5个数据。而不是复制代码来下载数据,最好是启动5个Intent来下载所有数据,从而利用各个用例。
我遇到的问题是我需要知道所有5次下载尝试的时间。我无法跟踪服务中的哪些下载,因为我使用的是IntentService。 BroadcastReceivers存在同样的问题,因为它们仅在onReceive方法的持续时间内存在。
我正在查看sendOrderedBroadcast,但这需要为每次下载尝试使用BroadCastReceiver。我还有read结果在发送完成时创建,但是因此下载完成后却没有?
“如果resultReceiver参数为非null,则指定a BroadcastReceiver的onReceive()方法将在调用时调用 发送有序广播意图完成。“
也许我可以尝试使用sendOrederedBroadcast并在传递的Intent中打包某种计数器?
答案 0 :(得分:1)
我有一个非常整洁的解决方案,似乎没有破坏任何Android范例。
<强>概述强> 想象一下IntentService响应六个动作。其中五个操作下载了一些数据,第六个操作是一次性下载所有数据的请求。最初的问题是如何在响应下载所有项目的操作时重用逻辑来下载五个项目。还需要在完成所有5次下载后收到通知。
<强>解决方案强> 当响应下载所有数据的操作时,IntentService构造一个ArrayList,其中包含与服务可以执行的每个下载操作相关的Intent Strings。 IntentService有效地调用自己传递下载的ArrayList来执行。每次服务执行下载时,它都可以“弹出”ArrayList中的第一个条目,然后再次调用自己。
ArrayList不必包含所有5次下载,它可能是所有可用下载的子集!每次下载尝试还可以启动任何Intent,在不中断下载“链”或最终通知的流程的情况下传达个人成功或失败。最后,只需要很少的代码来解决这个问题。
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(...)中的null检查允许IntentService继续执行各个下载操作,即IntentService仍然可以正常响应下载操作。
答案 1 :(得分:0)
如果你想管理多个线程,那么使用线程池执行器可能会有所帮助,
http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html
答案 2 :(得分:0)
为每个下载请求启动相同的服务,该请求启动一个新的异步任务,该任务在onPreExecute / onPostExecute&amp;中绑定和解除绑定。 onCancelled。
我不知道你是否可以将服务绑定到自身,如果可以的话会很有趣......