Nano Hash - криптовалюты, майнинг, программирование

Шаблон проектирования для модульной AsyncTask в Android

Я уже некоторое время использую AsyncTask в Android. Мне это нравится, потому что вы можете запускать асинхронно, в фоновом потоке, любую задачу, которую хотите (под задачей я подразумеваю блок кода).

Вначале каждый раз, когда задача должна выполняться асинхронно и/или в фоновом потоке, я объединял ее код в расширение AsyncTask. Иногда мне нужно было связать несколько таких задач (одну в зависимости от результата другой) и вызвать следующую в AsyncTask.onPostExecute(T data) (после завершения выполнения), но теперь я чувствую, что мой код загроможден таким большим количеством стандартного кода (скелет AsyncTask) и соединение последовательных задач.

Кроме того, мои AsyncTask иногда запускаются из другого AsyncTask, и Android может жаловаться. Например, если я хочу отобразить некоторые элементы до/после выполнения, это будет проблемой при вложении вызовов.

В частности, я ищу способ модульного выбора того, должна ли задача выполняться синхронно/асинхронно, последовательно/параллельно или вместе с другой. Мой выбор до сих пор заключался в том, чтобы иметь простой интерфейс Task, ожидающий реализации execute(T data) метода. Затем я могу связать один или несколько из них для последовательного или параллельного запуска, как определено в таких блоках, как этот:

public doMultipleActions() {
  runTask(new MyFirstParallelTask(myFirstData)); // running asynchronously in parallel the first task
  runTask(new MySecondParallelTask(mySecondData)); // running asynchronously in parallel the second task

  runTask(new MyFirstSequentialTask(myThirdData, new MySecondSequentialTask(myFourthData, new DummyCallback()))); // running asynchronously sequentially the third and fourth tasks
}

то есть runTask(Task t) запустит код Task.execute(T data) в блок кода AsyncTask.doInBackground(T... data). Последовательные задачи также предполагают выполнение другой задачи в блоке кода AsyncTask.onPostExecute(T data).

Я просмотрел несколько похожих вопросов: Можно ли последовательно связать асинхронную задачу (начиная одну после завершения предыдущей асинхронной задачи), Цепочка AsyncTask в действии (обратный вызов?), Как избежать объединения нескольких Вызовы AsyncTask?, наиболее близкие к моей проблеме, но я не смог найти ничего полезного, хотя я не думаю, что я единственный, кто имеет дело с этим.

Есть ли лучший способ, ожидаемый способ или даже шаблон проектирования для модульного использования AsyncTask в Android?


Ответы:


1

Несколько задач AsyncTask можно запускать последовательно или параллельно, используя executeOnExecutor с параметром AsyncTask.SERIAL_EXECUTOR или AsyncTask.THREAD_POOL_EXECUTOR.

Если вы ожидаете результат с помощью механизма ожидания (например, дождитесь завершения задачи и возврата результата), то лучше использовать Future. Одной из таких реализаций является FutureTask, которая использует Callable следующим образом:

ExecutorService pool = Executors.newFixedThreadPool(poolSize);
FutureTask<String> future = new FutureTask(new Callable() {
    public String call() {
        ...
    return res;
});
executor.execute(future);

String res = future.get(); 

Последняя строка заблокирует операцию до тех пор, пока Callable inside не вернет результат String. На самом деле вы даже можете установить тайм-аут для его завершения.

Помните, что AsyncTask выполняет не только асинхронные операции. Он также выполняет свой процесс в фоновом потоке. Таким образом, вы по-прежнему можете использовать AsyncTask (или Thread) для выполнения синхронных операций, которые в противном случае блокировали бы пользовательский интерфейс.

19.05.2015
  • Спасибо за ваше предложение, оно интересно, но я не понимаю, как оно отвечает на вопрос (который больше касается пакетной обработки AsyncTask, чем асинхронных задач). Я мог бы улучшить свой вопрос. Кроме того, выполнение нескольких задач внутри одного AsyncTask не равно множеству AsyncTask, обычно несколько AsyncTask могут выполняться параллельно. 19.05.2015
  • Прежде всего, AsyncTask означает Асинхронная задача. Во-вторых, вы ищете способ выбрать, должна ли задача выполняться асинхронно, после другой или вместе с другой, но, похоже, в вашем распоряжении есть только AsyncTask. На самом деле то, что вы делаете с цепочкой AsyncTask, технически формирует синхронный процесс (где следующий AsycTask ожидает первого). Итак, я делаю вывод, что вы ищете синхронный способ запуска процесса. 19.05.2015
  • Я вижу, ты прав. Это не то, что я ожидал, но я прочитаю документ, чтобы увидеть, как я могу его интегрировать. Спасибо 19.05.2015
  • Честно говоря, я перечитал ваш вопрос, и у меня сложилось впечатление, что вы хотите сделать это строго с AsyncTask. Я обновил свой ответ для этого. AsyncTask можно запустить последовательно или параллельно. Если вы стремитесь сделать именно это, то AsyncTaskexecuteOnExecutor подойдет. Есть предостережения относительно максимального количества AsycTask, которые могут выполняться одновременно, и различного поведения по умолчанию для разных API. На самом деле, если вы запускаете ICS, то по умолчанию он последовательный. Поэтому я бы использовал Future, если я ищу только результат, и AsyncTask, если хочу выполнять фоновую задачу и обновлять пользовательский интерфейс. 19.05.2015
  • Да, я не прошу другой инструмент, делающий что-то близкое к AsyncTask, AsyncTask мне подходит, но как модульно манипулировать этой концепцией. Ваш ответ заставил меня понять, что мой вопрос не фокусируется на правильных вещах (упаковке вместо инструмента AsyncTask). У меня еще не было времени попробовать ваше решение, я сделаю это в ближайшее время. 19.05.2015
  • Хорошо, я понял смысл FutureTask. Это не совсем то, что я искал, я обновил свой вопрос, но все же интересно узнать об этом, я мог бы использовать это позже. 19.05.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..