mik3y / usb-serial-for-android

Android USB host serial driver library for CDC, FTDI, Arduino and other devices.
MIT License
4.9k stars 1.59k forks source link

(Solution OK?) (SerialInputOutputManager) @UiThread must be executed on the main thread #365

Closed trueToastedCode closed 3 years ago

trueToastedCode commented 3 years ago

I tried to run it as a background job in a Flutter project like that:

usbIoManager = new SerialInputOutputManager(this.usbSerialPort, this);
new Thread(usbIoManager).start(); 

The Error:

W/SerialInputOutputManager(26078): Run ending due to exception: Methods marked with @UiThread must be executed on the main thread. Current thread: Thread-2
W/SerialInputOutputManager(26078): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Thread-2
W/SerialInputOutputManager(26078):  at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:1230)
W/SerialInputOutputManager(26078):  at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:862)
W/SerialInputOutputManager(26078):  at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:72)
W/SerialInputOutputManager(26078):  at io.flutter.embedding.engine.dart.DartExecutor$DefaultBinaryMessenger.send(DartExecutor.java:397)
W/SerialInputOutputManager(26078):  at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:97)
W/SerialInputOutputManager(26078):  at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:83)
W/SerialInputOutputManager(26078):  at com.truetoastedcode.serialconsole.serial_console.MainActivity.onNewData(MainActivity.java:114)
W/SerialInputOutputManager(26078):  at com.hoho.android.usbserial.util.SerialInputOutputManager.step(SerialInputOutputManager.java:234)
W/SerialInputOutputManager(26078):  at com.hoho.android.usbserial.util.SerialInputOutputManager.run(SerialInputOutputManager.java:204)
W/SerialInputOutputManager(26078):  at java.lang.Thread.run(Thread.java:923)

The most obvious thing to do would be to use runOnUiThread() but that blocks the UI. I found another solution by overwriting the library in SerialInputOutputManager.java

In the step() method i changed listener.onNewData(data); (line 233) to

new Handler(Looper.getMainLooper()).post(() -> {
    listener.onNewData(data);
});

Is this a good solution?

kai-morich commented 3 years ago

I recommend you do this in your onNewData method as shown here

trueToastedCode commented 3 years ago

Right ;D That works