Closed enricocaliolo closed 1 year ago
I've never tried it! feel free to submit a PR
I would think it would just work.
Are you doing this in your isolate?
void isolateFunction() async {
// Ensure that the Flutter engine is initialized
WidgetsFlutterBinding.ensureInitialized();
// isolate code
}
did you fix it?
Hi, sorry for the late reply. Using `WidgetsFlutterBinding.ensureInitialized' did not work. It gave the error: ' UI actions are only available on root isolate.' I also am not sure how I would implement a custom BinaryMessenger between the package and my app, so I haven't tested that.
For more context, I have a self-package outside the main app that handle the bluetooth communication between the app and the ESP I am using, as I need it for more than one app. I tried testing with the app example, but this package is far behind, so I would need to update it. This would be a lot of work, as the API changed a lot since I started, and it may won't even work, so I am deciding what to do.
Just tried with the example app (with the current version) to see if it worked, and it doesn't. When I use a function to connect to a device via compute(), it gives me the same error as it did previously.
Future<bool> connect(BluetoothDevice device) async {
try {
await device.connect();
return true;
} catch (e) {
print(e);
return false;
}
}
try {
WidgetsFlutterBinding.ensureInitialized();
result = await compute(connect, lastDevice);
} catch (e) {
print('ERRO: $e');
}
The actual functionality is a lot more complex than that, but it fails on the initial step of the connection. When I don't use isolates, it works as expected, but when I am on a custom isolate, it breaks and give the error mentioned previously.
WidgetsFlutterBinding.ensureInitialized();
should be in the new isolate. Not the current isolate. (however this may not work still: https://github.com/flutter/flutter/issues/10647)
Future<bool> connect(BluetoothDevice device) async {
WidgetsFlutterBinding.ensureInitialized();
try {
await device.connect();
return true;
} catch (e) {
print(e);
return false;
}
}
try {
result = await compute(connect, lastDevice);
} catch (e) {
print('ERRO: $e');
}
second, you should probably use Isolate. spawn()
, and not use compute
.
Plugins and channels can be used by any Isolate, but that Isolate has to be a root Isolate (the one created by Flutter) or registered as a background Isolate for a root Isolate.
The following example shows how to register a background Isolate in order to use a plugin from a background Isolate.
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
void _isolateMain(RootIsolateToken rootIsolateToken) async {
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
FlutterBluePlus.startScan();
}
void main() {
RootIsolateToken rootIsolateToken = RootIsolateToken.instance!;
Isolate.spawn(_isolateMain, rootIsolateToken);
}
WidgetsFlutterBinding.ensureInitialized();
can't be used outside the main isolate, so I ruled that out. Now, I tried setting the custom BinaryMessenger, but it still give me the same error, that I need to use WidgetsFlutterBinding.ensureInitialized();
or passing a custom BinaryMessenger instance to MethodChannel().
Well, I'll probably just update the package and refactor the code, as I delayed it enough, and then see what I can do. I'll probably report it back here in a few days. Thanks for the replies!
you need to use BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
did you try it?
it seems caused by _methods.setMethodCallHandler(_methodCallHandler); only can working on main isolate
Sorry for the late reply. Just updated the lib, but, unfortunately, it still don't work. I am passing the RootIsolateToken and setting BackgroundIsolateBinaryMessenger, but it still gives me the same error. At least in my app, I am not sure if this would work in the example either.
is all of your FBP code in the isolate?
mixing and matching would cause problems i think
No. It is on a different flutter project though, it may be related to this. I was passing the RootIsolateToken through the classes I use, dunno if this is optimal or not but it was the only way.
The only code I had on isolates was the connection. I need to confirm some characteristics to assert whether the device is a specific-one for my app or not.
When I have time, I can try putting an Isolate in the example app and see if it works, if you have not already, and then we can confirm for sure if this is a problem on my end or something related to the lib itself.
I'm going to close this. To get isolats to work all you need to do:
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
if this doesn't work, please open a new issue.
@chipweinberger im having the same sort of issues. Its down to a flutter limitation in setMethodCallHandler
this calls setMessageHandler
This is not supported with background isolates
More info : https://api.flutter.dev/flutter/services/BackgroundIsolateBinaryMessenger/setMessageHandler.html
Im unsure if this is something flutter_blue_plus can do while using setMethodCallHandler to have the platform code call back to flutter
Relates to this issue raised against core flutter
you can use https://pub.dev/packages/flutter_isolate or https://pub.dev/packages/isolate_handler to workaround this
@chipweinberger does that work ? I read the flutter engine code and all messages from calling methodChannel.invokeMethod
always lands the response on the root isolate
You could have the UI isolate forward the message on to your background isolate, but that probably defeats the point.
Requirements
Have you checked this problem on the example app?
No
FlutterBluePlus Version
1.12.13
Flutter Version
3.13.1
What OS?
Android
OS Version
Android 10
Bluetooth Module
Esp32
What is your problem?
Trying to connect to a device inside a different isolate results in this error:
The suggestion on the message error did not work. I want to ask if the current version supports connection via isolates, as I would need to refactor a bit of code to align my code with it, so knowing beforehand could save me a lot of trouble. Thanks.
Logs