Calling a UI method from Isolate listen method in Flutter throws exception
check important note 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.
Check Example,
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]);
}
AVEbrahimi
Untying an impossibly tangled knot is actually possible. For every problem, there is a solution. And I am just one who is interested in untying and solving, that's it :)
Updated on December 15, 2022Comments
-
AVEbrahimi over 1 year
I tried to use ovprogresshud (https://pub.dev/packages/ovprogresshud) to show download progress. I used flutter_downloader (https://pub.dev/packages/flutter_downloader) for download.
I try to update progress via an Isolate, but receive errors. (If I call Progresshud.showWithStatusdirectly in my code, say before download, it works)
My code:
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) {}, );
The error I receive:
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> ....
-
AVEbrahimi over 4 yearsI did same and called Progresshud.showWithStatus in
listen
but it throws exception -
Abhay Koradiya over 4 yearsdo not call
Progresshud.showWithStatus
. Only rebuild using setstate. and show that progress in build. -
AVEbrahimi over 4 yearsaha, so I should not use ovprogresshud? or I use something like ValueNotifier::addListener
-
Abhay Koradiya over 4 yearsyou can but you need to show it only from Build method.