Android - отслеживание нескольких действий в IntentService - PullRequest
2 голосов
/ 10 ноября 2011

Как я могу отследить количество N заданий - особенно, когда все N из них выполнены, и не удалось ли выполнить какое-либо задание.

Например, у меня есть служба, которая может ответить на 5 уникальных Интентов, чтобы загрузить 5 уникальных фрагментов данных с удаленного сервера.У меня также есть требование загрузить все 5 частей данных одновременно.Вместо того, чтобы дублировать код для загрузки данных, было бы неплохо запустить 5 Intents для загрузки всех данных, используя при этом отдельные варианты использования.

Проблема, с которой я столкнулся, заключается в том, что мне нужно знать, когда все 5попытки загрузки были сделаны.Я не могу отслеживать, какие загрузки были сделаны в службе, потому что я использую IntentService.Та же проблема существует для BroadcastReceivers в том, что они существуют только на время их метода onReceive.

Я смотрел на sendOrderedBroadcast, но это потребовало бы наличия BroadCastReceiver для каждой попытки загрузки.У меня также read результат создается после завершения отправки, но не поэтому, когда загрузка будет завершена?

"Если аргумент resultReceiver не равен NULL, он указываетBroadcastReceiver, метод onReceive () которого будет вызван, когда отправка заказанного широковещательного намерения завершится . "

Возможно, я мог бы попытаться использовать sendOrederedBroadcast и упаковать некоторый счетчик вНамерение, которое передается вокруг?

Ответы [ 3 ]

1 голос
/ 11 ноября 2011

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

Запускать ту же службу для каждого запроса на загрузку, которая запускает новую асинхронную задачу, которая связывает и отсоединяет себя в onPreExecute / onPostExecute & onCancelled.

Я не знаю, сможете ли вы привязать службу к себе,будь веселее, если сможешь ...

0 голосов
/ 10 ноября 2011

, если вы хотите управлять несколькими потоками, может оказаться полезным использование исполнителя пула потоков,

http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...