Флаттер - Как вычислить тяжелую задачу, которая включает будущее, не блокируя пользовательский интерфейс? - PullRequest
0 голосов
/ 17 февраля 2019

Я создаю приложение, которое извлекает сообщения из интернета как json.Я анализирую json в Post объекты в флаттер, используя фабрику.Объект Post включает заголовок, тело и изображение.Я отображаю эти сообщения в виде списка с помощью построителя списка.Тяжелая задача состоит в том, чтобы я вычислил 2 доминирующих цвета из изображения, чтобы установить в качестве фонового градиента элемента сообщения.Для этого я использую: https://pub.dartlang.org/packages/palette_generator

Я вычисляю 2 доминирующих цвета в фабрике парсеров json, потому что тогда у меня есть полный объект Post со всей необходимой информацией.Также, таким образом, мне не нужно вычислять цвета при рендеринге объекта Post.Я делаю это с помощью следующего кода:

Future<List> _getColors() async {
  Color gradientOne, gradientTwo;
  String imageUrl = json['image'];

  paletteGenerator = await PaletteGenerator.fromImageProvider(
      CachedNetworkImageProvider(imageUrl));

  gradientOne = paletteGenerator.colors.toList()[0];
  gradientTwo = paletteGenerator.colors.toList()[1];

  return [gradientOne, gradientTwo];
}

Я добавляю это в объект Post и в рендере я жду этого будущего:

post.gradientColors
    .then((result) => {
          gradient = result,
          this.setState(() {
                  loading = false;
                })
        })

В основном пользовательском интерфейсе я показываюиндикатор загрузки, пока все фьючерсы не разрешены.Для этого я использую следующий код:

List<Future> futures = [];

  for (var post in tmpList) {
    futures.add(post.gradientColors);
  }
  await Future.wait(futures)
      .then((result) => {list.addAll(tmpList)});
}

Это работает нормально, за исключением медленного пользовательского интерфейса при получении новых сообщений.После небольшого прочтения я обнаружил, что могу использовать изоляты во флаттере.Поэтому я изменил свою функцию синтаксического анализа, как описано здесь: https://flutter.io/docs/cookbook/networking/background-parsing

Это работает безупречно, и мое приложение работает без задержек, недостатком является то, что мои цвета не рассчитываются.По какой-то причине, когда я использую compute (), мое Future никогда не приходит к результату.

Возможно ли использовать compute в этой ситуации или есть лучший способ рассчитать цвета, не вызывая задержки в моем пользовательском интерфейсе?

EDIT

Я пытался программировать Isolate без вычислений, но цветовые фьючерсы по-прежнему не загружаются.Вот код, который я использовал:

ReceivePort receivePort = ReceivePort();
Isolate isolate = await Isolate.spawn(getMorePosts, receivePort.sendPort);
receivePort.listen((data) {
  list.addAll(data);
});

Я все данные получаю, но мое будущее не заканчивается.

1 Ответ

0 голосов
/ 17 февраля 2019

К сожалению compute() поддерживает только результаты синхронизации.

compute() прост и является просто оболочкой для облегчения запуска изолятов.

Вы можете просто запустить дополнительный изолятиспользуя пользовательский код и получить больше мощности.

https://api.dartlang.org/stable/2.1.1/dart-isolate/dart-isolate-library.html

Пакет изолят предоставляет некоторые удобные функции, облегчающие работу с изолятами.

...