【问题标题】:Calling a UI method from Isolate listen method in Flutter throws exception从 Flutter 中的 Isolate 监听方法调用 UI 方法抛出异常
【发布时间】:2019-12-04 07:22:26
【问题描述】:

我尝试使用 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>
....

【问题讨论】:

    标签: flutter dart download progress-bar dart-isolates


    【解决方案1】:

    查看重要说明here

    重要提示:您的 UI 在主隔离中呈现,而下载事件来自后台隔离(换句话说,回调中的代码在后台隔离中运行),因此您必须处理两个隔离之间的通信。

    检查示例,

    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]);
    }
    

    【讨论】:

    • 我做了同样的事情并在listen 中调用了 Progresshud.showWithStatus 但它抛出了异常
    • 请勿致电Progresshud.showWithStatus。仅使用 setstate 重建。并显示构建进度。
    • 啊哈,所以我不应该使用 ovprogresshud?或者我使用类似 ValueNotifier::addListener
    • 可以,但只需要从 Build 方法中显示即可。
    猜你喜欢
    • 2017-05-31
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2011-10-22
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多