I have been implementing ble scan in my flutter app and i need scan to be in an isolate, so that it doesn't effect the execution of UI in main thread, but using ble scan in flutter blue plus in an isolate gives me this error,
E/flutter ( 5598): [ERROR:flutter/runtime/dart_isolate.cc(1097)] Unhandled exception:
E/flutter ( 5598): 'package:flutter/src/services/platform_channel.dart': Failed assertion: line 542 pos 7: '_binaryMessenger != null || BindingBase.debugBindingType() != null': Cannot set the method call handler before the binary messenger has been initialized. This happens when you call setMethodCallHandler() before the WidgetsFlutterBinding has been initialized. You can fix this by either calling WidgetsFlutterBinding.ensureInitialized() before this or by passing a custom BinaryMessenger instance to MethodChannel().
E/flutter ( 5598): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
E/flutter ( 5598): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
E/flutter ( 5598): #2 MethodChannel.setMethodCallHandler (package:flutter/src/services/platform_channel.dart:542:7)
E/flutter ( 5598): #3 FlutterBluePlus._initFlutterBluePlus (package:flutter_blue_plus/src/flutter_blue_plus.dart:395:20)
E/flutter ( 5598): #4 FlutterBluePlus._invokeMethod (package:flutter_blue_plus/src/flutter_blue_plus.dart:557:7)
E/flutter ( 5598): <asynchronous suspension>
E/flutter ( 5598): #5 FlutterBluePlus.adapterState (package:flutter_blue_plus/src/flutter_blue_plus.dart:134:20)
E/flutter ( 5598): <asynchronous suspension>
E/flutter ( 5598): #6 _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:152:3)
E/flutter ( 5598): <asynchronous suspension>
my code UI
ElevatedButton(
onPressed: () {
//isolate scan test
ReceivePort receivePort = ReceivePort();
receivePort.listen((message) {
log('GOT MESSAGE $message');
receivePort.close();
});
Isolate.spawn(bluetoothScanning, receivePort.sendPort);
},
child: const Text('Scan for Devices'),
),
Here on pressing the button it calls a new Isolate for the function, and the function is
void bluetoothScanning(SendPort msg) async{
Set<DeviceList>? device = await BluetoothScreen().scan();
return msg.send(device);
}
Here BluetoothScreen() is calling the instance of class which listen for bluetooth connection
BluetoothScreen1() {
var subscription = FlutterBluePlus.onScanResults.listen((results) {
if (results.isNotEmpty) {
ScanResult r = results.last; // the most recently found device
deviceList.add(
DeviceList('${r.device.remoteId}', r.advertisementData.advName,r.device));
}
}, onError: (e) => log('Error $e'));
FlutterBluePlus.cancelWhenScanComplete(subscription);
}
and scan() method scan for the devices,
Future<Set<DeviceList>> scan() async {
log('BLE SCAN ENTERED');
await FlutterBluePlus.adapterState
.where((val) => val == BluetoothAdapterState.on)
.first;
await FlutterBluePlus.startScan(timeout: const Duration(seconds: 5));
await FlutterBluePlus.isScanning.where((val) => val == false).first;
return deviceList;
}
I have tried using, WidgetsFlutterBinding.ensureInitialized(); ,in the main() method, but I think UI initialized on main thread, the isolate doesn't know about this. The isolate is giving error that the UI is not initialized.
How to implement this so that scanning for bluetooth doesn't effect the execution of UI in main thread?