У меня есть решение, которое действительно довольно аккуратное и не нарушает никаких парадигм 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 по-прежнему реагирует на загрузку действий как обычно.