Как эффективно управлять несколькими задачами Async на Android

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

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

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

Мой вопрос:

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

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

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

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

Solutions Collecting From Web of "Как эффективно управлять несколькими задачами Async на Android"

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

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

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

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

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

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

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

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

ExecutoreService и CountDownLatch

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

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

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

  • Increments finishedTasks

  • If finishedTasks == 6 затем запустите 1 общедоступный метод для обновления интерфейса пользователя

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