flutter - 从 Flutter 中的 Isolate 监听方法调用 UI 方法会抛出异常

标签 flutter dart download progress-bar dart-isolates

我尝试使用 ovprogresshud ( https://pub.dev/packages/ovprogresshud ) 显示下载进度。我使用 flutter_downloader ( https://pub.dev/packages/flutter_downloader ) 进行下载。

我尝试通过隔离更新进度,但收到错误。 (如果我直接在代码中调用 Progresshud.showWithStatus,比如在下载之前,它就可以工作)

我的代码:

ReceivePort _port = ReceivePort();
...

IsolateNameServer.registerPortWithName(
        _port.sendPort, 'downloader_send_port');
_port.listen(
      (dynamic data) {
        String id = data[0];
        DownloadTaskStatus status = data[1];
        int progress = data[2];
        if (status == DownloadTaskStatus.complete) {
        } else if (status == DownloadTaskStatus.running) {
          Progresshud.showWithStatus("%$progress Downloaded");
        }
      },
      onDone: () {
        checkIfDictionaryUnzipped(DBFilePath);
      },
      onError: (error) {},
    );

我收到的错误:

Unhandled Exception: PlatformException(error, Attempt to invoke virtual method 'android.view.ViewParent android.view.ViewGroup.getParent()' on a null object reference, null)
E/flutter (29114): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
E/flutter (29114): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:321:33)
E/flutter (29114): <asynchronous suspension>
E/flutter (29114): #2      Progresshud.showWithStatus (package:ovprogresshud/progresshud.dart:18:27)
E/flutter (29114): <asynchronous suspension>
....

最佳答案

查看重要说明here

Important note: your UI is rendered in the main isolate, while download events come from a background isolate (in other words, codes in callback are run in the background isolate), so you have to handle the communication between two isolates.

检查示例,

ReceivePort _port = ReceivePort();

@override
void initState() {
    super.initState();

    IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
    _port.listen((dynamic data) {
        String id = data[0];
        DownloadTaskStatus status = data[1];
        int progress = data[2];
        setState((){ });
    });

    FlutterDownloader.registerCallback(downloadCallback);
}

@override
void dispose() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
    super.dispose();
}

static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
    final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
    send.send([id, status, progress]);
}

关于flutter - 从 Flutter 中的 Isolate 监听方法调用 UI 方法会抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59170836/

相关文章:

android - 如何遍历dart中的以下循环?

arrays - 在 Flutter Cards 中插入 JSON 信息?

google-analytics - Google Analytics(分析)事件跟踪-不适用于下载链接

android - 下载管理器在使用平台默认值的 Android Pie 9.0 NetworkSecurityConfig : No Network Security Config specified, 中不起作用

flutter - 如何在项目网格列表中的图像内添加文本和一些内容

json - 将 json 响应转换为字符串并将其放入结构中

search - Flutter Firestore Query Listen - 无法引用 Listen 中的变量

flutter - 如何解决 “MediaQuery.of() called with a context that does not contain a MediaQuery.”的错误?

Flutter - Dart - setState 在与异步函数的 Future<> 一起使用时不会重新加载状态

java - 文本/csv文件下载在百行时转换为文本/纯文本