调用MethodChannel时如何发送异步响应?

发布于 2025-01-18 08:52:07 字数 2109 浏览 0 评论 0原文

Flutter官方文档说,我们不能将EventChannel用于扑动和本机代码之间的方向通信,只能在本机的聆听事件上进行。

因此,方法通道是从扑波代码上调用本机方法的唯一推荐方法。我的问题是,我使用的是一种调用异步例程打印的热打印机,包括在主UI线程外运行的内部听众。 This is the error that I get:

/JavaBinder( 6792): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Binder_2

That way I can't use a simple Future to return something to Flutter, because I can't send results from listeners.

问题:如何创建一个EventChannel,可以通过MethodChannel调用可以访问其EventSink?

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "unique.identifier.method/call";
    private static final String CHANNEL_STREAM = "unique.identifier.method/stream";
    private Printer printer = new Printer(getApplicationContext());

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL).setMethodCallHandler(
                (call, result) -> {
                    // Note: this method is invoked on the main thread.
                    String method = call.method;
                    if(method == "print"){
                        printer.startPrint(new OnPrintListener.Stub() {
                            public void onFinish() throws RemoteException {
                                printer.cutPaper();
                                //Question: how to send event from this point?
                            }
                            public void onError(int i) throws RemoteException {
                                //Question: how to send error event from this point?
                                throw new RemoteException("Print exception: "+i);
                            }
                        });
                        //it returns true before printing has been finished 
                        result.success(true);
                    }
                }
        );
    }
}

Flutter official documentation says we can't use EventChannel for both-direction communication between Flutter and Native code, only on listening events from Native.

So the MethodChannel is the only recommended way to call a method on native from Flutter code. My problem is that I'm using a Thermal Printer that calls an asynchronous routine to print, including internal listeners that run outside the main UI thread.
This is the error that I get:

/JavaBinder( 6792): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Binder_2

That way I can't use a simple Future to return something to Flutter, because I can't send results from listeners.

Question: How can I create an EventChannel whose EventSink can be accessed by a MethodChannel call?

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "unique.identifier.method/call";
    private static final String CHANNEL_STREAM = "unique.identifier.method/stream";
    private Printer printer = new Printer(getApplicationContext());

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL).setMethodCallHandler(
                (call, result) -> {
                    // Note: this method is invoked on the main thread.
                    String method = call.method;
                    if(method == "print"){
                        printer.startPrint(new OnPrintListener.Stub() {
                            public void onFinish() throws RemoteException {
                                printer.cutPaper();
                                //Question: how to send event from this point?
                            }
                            public void onError(int i) throws RemoteException {
                                //Question: how to send error event from this point?
                                throw new RemoteException("Print exception: "+i);
                            }
                        });
                        //it returns true before printing has been finished 
                        result.success(true);
                    }
                }
        );
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文