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实例或者插件实例了。

java 复制代码
// 省略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 页面中的调用

java 复制代码
TestPlugin.getChannel().invokeMethod("onMessageReceived", "这里是发送的信息");

Flutter 页面中接收到信息

Dart 复制代码
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,果然奏效。

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

相关推荐
wstcl32 分钟前
安卓app、微信小程序等访问多个api时等待提示调用与关闭问题
android·微信小程序·webapi
dragon7251 小时前
关于image组件设置宽高不生效问题的探究
flutter
louisgeek2 小时前
Android Studio 打印中文乱码
android
会煮咖啡的猫2 小时前
Flutter 是否需要 UI 组件库?
flutter
眼镜会飞2 小时前
Flutter 3.x新版android端的build.gradle.kts文件配置arm64-v8a和armeabi-v7a等
android·前端·flutter
vocal2 小时前
【我的安卓第一课】Activity 的伙伴 Fragment
android
Nayuta3 小时前
字节跳动「移动 OS 部门」招聘安卓工程师,AI+OS 方向
android
00后程序员张4 小时前
iOS 应用上架常见问题与解决方案,多工具组合的实战经验
android·ios·小程序·https·uni-app·iphone·webview
恋猫de小郭4 小时前
Flutter 小技巧之有趣的 UI 骨架屏框架 skeletonizer
android·前端·flutter
Kapaseker4 小时前
Kotlin 老手怎么写代码?
android·kotlin