rmawatson / flutter_isolate

Launch an isolate that can use flutter plugins.
MIT License
262 stars 80 forks source link

Unable to pass List<Uint8List> #142

Closed tnghieu closed 10 months ago

tnghieu commented 10 months ago
@pragma('vm:entry-point')
void startProcessingImagesInBackground(List<List<Uint8List>> imageFiles) async {
  await FlutterIsolate.spawn(separateBatches, imageFiles);
}

@pragma('vm:entry-point')
void separateBatches(List<List<Uint8List>> imageFiles) async {
  for (List<Uint8List> images in imageFiles) {
    await flutterCompute(processBatch, images);
  }
}

@pragma('vm:entry-point')
Future<List<ResultObjectDetection>> processBatch(List<Uint8List> images) async {
  List<ResultObjectDetection> resultsForThisBatch = [];
  for (Uint8List image in images) {
    List<ResultObjectDetection> results =
        await objectDetectionModel.getImagePrediction(
      image,
      minimumScore: 0.75,
      preProcessingMethod: pt_model.PreProcessingMethod.native,
    );
    resultsForThisBatch.addAll(results);
  }
  return resultsForThisBatch;
}

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument: is a Type: Uint8List

Unable to process this data with flutter_isolate. Can I only pass primitive types?

nmfisher commented 10 months ago

Reproducible on iOS simulator.

Also reproducible with pure Dart isolates:

main1.dart

import 'dart:isolate';
import 'dart:typed_data';

void main() async {
  await Isolate.spawnUri(Uri.parse('main2.dart'), [], <Uint8List>[
    Uint8List.fromList([1])
  ]);
  await Future.delayed(Duration(seconds: 5));
}

main2.dart

import 'dart:typed_data';

@pragma('vm:entry-point')
void main(List<String> args, Uint8List message) {
  print(args);
}
> dart run main1.dart 
Unhandled exception:
Invalid argument: is a Type: Uint8List
#0      Isolate._spawnUri (dart:isolate-patch/isolate_patch.dart:532:25)
#1      Isolate.spawnUri (dart:isolate-patch/isolate_patch.dart:459:7)
#2      main (package:flutter_isolate_example/main1.dart:5:17)
#3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#4      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
nmfisher commented 10 months ago

@tnghieu I doubt this is functioning correctly so I will file an issue against the dart-lang/sdk repository. If you need an immediate workaround, I suggest you pass things around as List<List<int>> rather than List<Uint8List>

https://github.com/dart-lang/sdk/issues/53890

nmfisher commented 10 months ago

Fix has been merged into the dartlang SDK, so wait for that to appear upstream and bump your SDK version number.

In the meantime, try sending as List<List> or wrapping with TransferableTypedData (suggested by Dart maintainers, I haven't actually tried that myself).