TransWikia.com

Как при создании изолята во Flutter, передать ему данные?

Stack Overflow на русском Asked by Yuri Petrov on September 28, 2020

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

Есть список в отдельном файле, всем доступен через импорт

List<String> strings;

Я создаю новый изолят

ReceivePort _receivePort = ReceivePort();
Isolate _isolate = await Isolate.spawn(newIsolate, _receivePort.sendPort);

В новом изоляте пытаюсь получить считать массив strings но он null.

newIsolate(SendPort sendPort) async {
   List<String> list = strings 
}

Получается надо как то этот список передать в новый изолят при создании или через порт.
Как можно это сделать?

One Answer

Для начала нужно понять, что изначально мы работаем в одном Isolate (он всегда запускается автоматический в main()). Сообщения межу Isolate налаживается при помощи:

  1. ReceivePort (принимающий)
  2. SendPort (отправляющий, отправлять можно только примитивные типы: null, num, bool, double, String)

Пример двухстороннего сообщения между Isolate:

import 'dart:io';
import 'dart:async';
import 'dart:isolate';

void main() async {
  // Создаем изолят и получаем его SendPort
  SendPort mainToIsolateStream = await initIsolate();
  // Отправляем через SendPort сообщение в изолят
  mainToIsolateStream.send('This is from main()');
}

Future<SendPort> initIsolate() async {
  // Completer для получения SendPort из изолята
  Completer completer = new Completer<SendPort>();
  // ReceivePort чтобы прослушивать изолят
  ReceivePort isolateToMainStream = ReceivePort();

  // Начинаем слушать изолят
  isolateToMainStream.listen((data) {
    // Фильтруем чтобы получить SendPort иначе получаем сообщения
    if (data is SendPort) {
      // отправляем SendPort в main через return (см. ниже)
      completer.complete(data);
    } else {
      print('[isolateToMainStream] $data');
    }
  });

  // Создаем изолят и отправляем в него SendPort из main
  Isolate myIsolateInstance = await Isolate.spawn(myIsolate, isolateToMainStream.sendPort);

  // отправляем SendPort в main
  return completer.future;
}

void myIsolate(SendPort isolateToMainStream) {
  // ReceivePort чтобы прослушивать изолят из main
  ReceivePort mainToIsolateStream = ReceivePort();
  // отправляем в него SendPort изолята
  isolateToMainStream.send(mainToIsolateStream.sendPort);

  // Начинаем слушать изолят из main
  mainToIsolateStream.listen((data) {
    print('[mainToIsolateStream] $data');
    // Закрываем
    exit(0);
  });

  // Отправляем через SendPort сообщение в main
  isolateToMainStream.send('This is from myIsolate()');
}

Correct answer by MiT on September 28, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP