Как эффективно управлять несколькими асинхронными задачами в Android - PullRequest
12 голосов
/ 10 февраля 2012

У меня есть сценарий, когда мне нужно будет сделать шесть http-вызовов на мой сервер, чтобы получить данные для шести различных элементов. Эти серверные вызовы не могут быть объединены, и они должны быть такими. Например: если вам нужна информация о расценках для GOOGLE, отправьте запрос на сервер, запрашивающий информацию о расценках Google. Затем, если вам нужны Yahoo, вы инициируете еще один http-вызов и т. Д.

Вот ситуация:

  1. Теперь мой конечный пользователь хочет сравнить 6 разных компаний.
  2. Как я уже говорил, для меня невозможно избежать 6 http-вызовов, для которых я использую 6 асинхронных задач.
  3. По мере получения каждого ответа на задачу Async я обновляю пользовательский интерфейс новыми данными.
  4. Плохой пользовательский интерфейс, если я обновляю его 6 раз за очень короткий промежуток времени.
  5. Это дает мерцающий эффект моему интерфейсу, который нежелателен.

Мой вопрос:

  1. Как можно отложить обновление пользовательского интерфейса, пока не получу все 6 ответов на асинхронные задачи?
  2. Я понимаю, что каждое задание не зависит друг от друга. Должен ли я запустить цикл while и подождать, пока получу все ответы?
  3. Есть ли лучший способ сделать это, а не цикл while, потому что если какой-либо из вызовов не отвечает, я застряну в ожидании навсегда.

Примечание. Я думаю, Android 1.6+ выполняет асинхронные задачи параллельно.

Это больше вопрос дизайна, и я был бы признателен за любую помощь в этом.

Заранее спасибо

Ответы [ 4 ]

4 голосов
/ 10 февраля 2012

Вы можете создать объект пула AsyncTask, который позволит вам подделать «пакетный» http-вызов.

  1. создайте наблюдаемую коллекцию AsyncTasks, я буду называть эту коллекцию вашим пулом
  2. ваша активность создает AsyncTasks (но еще не выполняет) и добавляет их в пул
  3. Активность регистрируется как наблюдатель пула
  4. Активность указывает пулу на выполнение, в свою очередь вызовы пула выполняются для каждой из его задач
  5. Когда задачи завершаются (как для успешных, так и для неудачных), они сохраняют данные ответов в пуле, и пул помечает задачу как «завершенную»
  6. Как только все Задачи помечены как выполненные, Пул уведомляет об активности прослушивания.

Общая идея заключается в том, чтобы пул знал, сколько задач и ожиданий, и сохранял совокупные данные о завершенных вызовах. Как только все закончено, уведомите Наблюдающую активность и передайте обратно все данные.

Вам нужно будет выяснить, как AsyncTasks сообщают пулу, что они завершены. Может быть, просто есть реализация AsyncTask, которая принимает конструктор пула, чтобы задачи имели ссылку на пул.

1 голос
/ 28 октября 2014

здесь только в темноте, но у вас есть:

  • 1x основной поток пользовательского интерфейса
  • 6x фоновых асинхронных задач, которые имеют: 6x методов для выполнения в фоновом режиме 6x методов для возврата данныхв пользовательский интерфейс (передний план)

почему бы не иметь переменную общедоступной области видимости в потоке пользовательского интерфейса, скажем, " FinishTasks ", тогда тот же метод в каждом из 6x потоков возвращаемых данныхчто:

  • увеличивает готовые задачи

  • , если готовые задачи == 6, затем запустите 1 открытый метод для обновления пользовательского интерфейса

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

1 голос
/ 21 февраля 2012

Я нашел это решение более подходящим для моей проблемы. Эта ссылка описывает несколько способов установить это. 1. ExecutorService 2. ExecutoreService и CountDownLatch

ExecutoreService и CountDownLatch

1 голос
/ 10 февраля 2012

Есть много способов, которыми вы могли бы справиться с этим:

  • Другой AsyncTask, который объединяет ответы от сетевых задач.
  • Выполните sendEmptyMessageDelayed() каждые, скажем, 500 мс до Handler, созданного вашим Activity, который обновляет данные, поступившие из сетевых задач, и продолжает делать это, пока не будут обработаны все сетевые результаты.
  • Поток, который выполняет агрегацию.

Будь это я, я бы, наверное, пошел с Handler.Подводя итог, пусть ваши сетевые задачи хранят данные в некотором промежуточном хранилище.Отправьте отложенные сообщения обработчику и в рамках проверки handleMessage() на данные в промежуточном хранилище и опубликуйте обновленные результаты.Если есть ожидающие результаты, отправьте отложенное сообщение снова.

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