当前位置: 首页 > article >正文

Flutter踩坑:原生安卓页面向Flutter通信

Flutter踩坑:原生安卓页面向Flutter通信

前言

Flutter APP 的开发过程中,有时不仅需要使用 Flutter 提供的组件,还需要使用原生的组件。

例如在对接外部 SDK 时,如果自己重新实现 SDK 的逻辑,无疑是本末倒置。

前文中我们已经接入并且打开了原生安卓的页面,也就是说主动通信已经完成。

真实的项目中,肯定不可能只有 Flutter 向原生安卓通信,肯定也原生安卓向 Flutter 发送信息。

操作其实很简单,就是将 method channel 的调用,反过来,由原生执行 invokeMethod ,由 Flutter 接收 method

但是这里面有很多坑。

执行

在插件中实例化MethodChannel,并且注册 MethodCallHandler

同时将这个 MethodChannel 放到静态变量中,以便在 Java 页面中调用。

这个我在网上搜了很多方式,都是让实例化 Flutter Engine 或者实例化 plugin 插件,但是实际上都没能成功,估计重新实例化的已经不是当前的这个 Flutter Engine实例或者插件实例了。

// 省略import
public class TestPlugin implements FlutterPlugin, MethodCallHandler,ActivityAware {
  static public MethodChannel channel;

  private Activity activity;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    TestPlugin.channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "test_plugin");
    TestPlugin.channel.setMethodCallHandler(this);
  }

  static public MethodChannel getChannel(){
    return TestPlugin.channel;
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    System.out.println( "================ 收到方法调用 ==========");
    System.out.println( call.method);
    if (call.method.equals("openNativePage")) {
      if (activity != null) {
        Intent intent = new Intent(activity, MainActivity.class);
        activity.startActivity(intent);
        result.success("Native page opened");
      } else {
        result.error("ACTIVITY_NOT_AVAILABLE", "Activity is not available", null);
      }
    } else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    TestPlugin.channel.setMethodCallHandler(null);
  }

  @Override
  public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
    activity = binding.getActivity();
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {
    activity = null;
  }

  @Override
  public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
    activity = binding.getActivity();
  }

  @Override
  public void onDetachedFromActivity() {
    activity = null;
  }
}

Java 页面中的调用

TestPlugin.getChannel().invokeMethod("onMessageReceived", "这里是发送的信息");

Flutter 页面中接收到信息

MethodChannel("test_plugin").setMethodCallHandler((call) async {
  print("接到方法调用: ${call.method}");
  if (call.method == 'onMessageReceived') {
    final String message = call.arguments as String;
    print('========aaa Received message from android: $message');
    // TODO: 处理接收到的信息
  }
});

总结

原生向 Flutter 发送信息时,会遇到许多莫名其妙的问题,网上搜了很多方法,但是都无效。

例如安卓原生页面直接继承 FlutterActivity,重新拿到 FlutterEngine实例然后实例化MethodChannel,但是真机调试时报设备不支持GooglePlay服务。

还有直接实例化插件类等等方式都不能成功。

因此我换用了在插件中直接使用静态变量传递已经初始化好的 MethodChannel,果然奏效。

当然,我觉得这个问题应该有更好的解决方案,但是目前没有找到,先使用这个方式解决问题,以作记录。


http://www.kler.cn/a/400066.html

相关文章:

  • 深度学习:计算卷积神经网络中输出特征图尺寸的关键公式
  • Java项目实战II基于Java+Spring Boot+MySQL的共享汽车管理系统(源码+数据库+文档)
  • Skywalking搭建-来自于图灵课堂
  • ScubaGear:用于评估 Microsoft 365 配置是否存在安全漏洞的开源工具
  • vulhub之log4j
  • WPF Gif图谱 如果隐藏的话会存在BUG
  • android通过广播设置默认启动器
  • 【Pikachu】XML外部实体注入实战
  • Loopy为何成为IP联名新顶流,如何赋能品牌营销新高度?
  • 用Ruby编写一个自动化测试脚本,验证网站登录功能的正确性。
  • TCP/IP协议浅析
  • 前端三大件之CSS
  • opencv调整图片对比度和亮度
  • 大模型(LLMs)推理面
  • 微信小程序点击跳转打电话功能
  • 实操案例|TinyVue树表+动态行合并
  • 【验证码逆向专栏】vaptcha 手势验证码逆向分析
  • StructuredStreamingKafka中的实时ETL案例及常见问题
  • 三维测量与建模笔记 - 点特征提取 - 4.3 Harris特征点
  • React Native 全栈开发实战班 - 网络与数据之数据缓存策略SWR、Query
  • 基于Cnn神经网络虫害预测
  • 基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】
  • Visual Studio 圈复杂度评估
  • 一体化运维监控管理平台:产品架构与功能解析
  • 量化交易系统开发-实时行情自动化交易-3.4.3.2.期货交易数据
  • 梯度提升树(Gradient Boosting Trees)详解