android 与 flutter 之间的通信

news2025/4/22 5:35:24

文章目录

  • 前言
  • 集成 flutter 混合开发
  • android 与 flutter 之间的通信
  • 总结
一、前言

因为flutter 具有跨平台的属性,既可以在android上跑,也能在ios 上跑,所以为了节约开发的成本,减少人力,势必就会用到它。然而已有的项目部不太可能重新写,所以就需要进行混合开发。也就是在原生中集成flutter,进行混合开发。混合开发就会遇到原生和flutter的通信问题,今个就讲讲原生和flutter的通信。

二、首先创建个flutter module,然后集成到app中

1、在原生项目的父目录下,使用命令,创建flutter项目:
flutter create -t module --org com.example flutter_demo
在这里插入图片描述
创建完毕,然后我们用as打开这个父目录,可以看到我们的flutter_demo 已经创建好了,如图:
在这里插入图片描述
2、在原生app里面的settings.gradle,include ‘:app’ 下面添加:

setBinding(new Binding([gradle: this]))
evaluate(new File(
    settingsDir.parentFile,
    'flutter_demo/.android/include_flutter.groovy'
))
include ':flutter_demo'

3、在原生app下的build.gradle中添加依赖:

dependencies {
	//...
	implementation project(':flutter')
}

添加完毕,我们切回 app的项目,运行会发现报错了。
在这里插入图片描述
报错是说flutterPlugin 没法用,这里在settings.gradle 将repositoriesMode改为:RepositoriesMode.PREFER_PROJECT。重新运行。
如果还遇到第三方解析失败,添加maven:

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
  repositories {
    maven { url 'https://jitpack.io' }
    maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'https://maven.aliyun.com/repository/central' }
    maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
    google()
    mavenCentral()
  }
}

另外在项目的build.gradel 添加:

allprojects {
  repositories {
    maven { url 'https://jitpack.io' }
    maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'https://maven.aliyun.com/repository/central' }
    maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
    google()
    mavenCentral()
  }
}

然后运行app,就可以了。如果你还有其他报错,切换到根目录,去检查下flutter_demo里头的这两个文件。打开main.dart,提示你Enable Dart support,点击它就可以。然后再打开 pubspec.yaml ,点击pub get 获取相应的依赖。确保flutter项目的环境和依赖库没问题。

到这里,我们的flutter_demo 就集成到我们的app中了。接下来就是看android和flutter的通信

三、android和flutter的通信

上面的项目,每次要看flutter代码是不是每次都要切过来切过去的,所以呢,我们可以在setting.gradle 加上这么一行代码:
project(‘:flutter_demo’).projectDir = new File(‘…/flutter_demo’)
在这里插入图片描述
这样,我们在app的项目中就能查看flutter的代码了。好了,我们最想知道的就是android 怎么打开 flutter页面。接这往下看。

1、android 跳转 flutter:
在清单AndroidManifest里面添加 FlutterActivity

    <activity android:name="io.flutter.embedding.android.FlutterActivity"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize"
        >
    </activity>

点击跳转:

   binding.fab.setOnClickListener { view ->
      //跳转flutter
      startActivity(
        FlutterActivity.createDefaultIntent(this)
      )
    }

你会发现跳转很慢,所以,我们用带有缓存引擎的初始路由来启动FlutterActivity
创建一个MyApplication 然后 在onCreate 中进行缓存引擎的初始化。

    // 创建一个Flutter引擎
    flutterEngine = new FlutterEngine(this);

    // 开始执行 Dart 代码来预热flutter引擎
    flutterEngine.getDartExecutor().executeDartEntrypoint(
      DartExecutor.DartEntrypoint.createDefault()
    );

    //缓存Flutter引擎用来开启FlutterActivity
    FlutterEngineCache
      .getInstance()
      .put("my_engine_id", flutterEngine);
  }

这个我们就能使用缓存引擎跳转Flutter。

 binding.fab.setOnClickListener { view ->
      //跳转flutter
      startActivity(
        FlutterActivity
          .withCachedEngine("my_engine_id")
          .build(this)
      );
    }

很明显立马就跳转过去了。

2、如何跳转不同的flutter页面?
在applation 的onCreate 初始化需要跳转的页面, 到我们的Application 中的onCreate添加:

flutterEngine.getNavigationChannel().setInitialRoute("/test2");

然后修改main.dart 的代码:

void main() => runApp(_widgetForRoute(window.defaultRouteName));

Widget _widgetForRoute(String route) {
switch (route) {
 case '/test1':
   return const Test1();
 case '/test2':
   return const Test2();
 case '/test3':
   return const Test3();
 default:
   return const Test1();
}
}

Test1是Test1.dart,代表不同的页面。当我们要跳转不同的页面,只要修改
flutterEngine.getNavigationChannel().setInitialRoute(“/test2”);就可以了,比如我们要跳转到Test3页面改成 flutterEngine.getNavigationChannel().setInitialRoute(“/test3”);
这个很简单,根据不同的标识,跳转对应的页面就行了。

四、接下来,就是文章的主题,讲通信方式都有哪些?

BasicMsgChannel
EventChannel
MethodChannel

1、BasicMsgChannel 方式
双向的,原生可以给flutter发送,然后flutter同时也可以返回信息给原生

发送:

    val flutterEngine = MyApplication.flutterEngine
    val basicMessageChannel = BasicMessageChannel(
      flutterEngine.dartExecutor.binaryMessenger,
      "basicMessageChannel",
      StringCodec.INSTANCE
    )
    basicMessageChannel.send("通过basicMessageChannel发送消息"){
        message: String?->
      Log.d("ssz", "接收:$message") //message 是flutter发回给原生的消息
    }

flutter 接收:

_basicMessageChannel = const BasicMessageChannel('basicMessageChannel', StringCodec());
    _basicMessageChannel.setMessageHandler((String? message) => Future<String>((){
      setState(() {//刷新控件
        _basicMessage = "flutter接收了消息:${message!}";
      });
      return "flutter 收到了";//这里是返回信息给原生
    }));

我们也可以反过来,原生接收,flutter发送,如下:
原生接收:

    basicMessageChannel.setMessageHandler { message, reply ->
      Log.d("ssz", "接收:$message")
    }

flutter 发送:

      _basicMessageChannel.send("我是flutter的消息");

2、MethodChannel 方法
主要是flutter 调用原生

原生接收:

val methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "test2")
    binding.btnTest2.setOnClickListener {
      toFlutter()
      methodChannel.setMethodCallHandler { call, result ->
        if (call.method.equals("open")){
          Log.d("ssz", "接收flutter调用")
        }
      }
    }

flutter 发送

 const _methodChannel = MethodChannel('test2');
    _methodChannel.invokeListMethod("open");

3、EventChannel方法
主要是原生发送给flutter,这个方法使用不当就会接受不到,谨慎使用。

原生发送:

 val eventChannel = EventChannel(MyApplication.flutterEngine.dartExecutor.binaryMessenger, "test3")
    binding.btnTest3.setOnClickListener {
      toFlutter()
      eventChannel.setStreamHandler(object : StreamHandler{
        override fun onListen(arguments: Any?, events: EventSink?) {
          Log.d("ssz","执行了 onListen");
          events?.success("原生发送")
        }
        override fun onCancel(arguments: Any?) {
        }
      })

    }
  }

flutter 接收

void initState() {
    super.initState();
    Future.delayed(const Duration(milliseconds: 6000), () {//需要做个延迟,不然原生onListen会不执行,导致不能发送消息
      var eventChannel = const EventChannel("test3");
      eventChannel.receiveBroadcastStream().listen((dynamic event) {
        setState(() {
          _EventMessage = "flutter接收$event";
        });
      }, onError: (dynamic error){
        setState(() {
          _EventMessage = "flutter接收$error";
        });
      },cancelOnError: true);
    });

  }

最后呢,关于路由方面,有的业务可能需要跳转很多不同的页面,原生的方式不太友好,可以选择闲鱼开源的库 https://github.com/alibaba/flutter_boost ,提高开发的效率。

以上代码地址:https://github.com/shenshizhong/HybridFlutter

总结

总的来讲:
1、android集成flutter,进行混合开发
2、android 与 flutter 的通信
3、使用第三方提高开发效率

如果对你有一点点帮助,那是值得高兴的事情。:)
我的csdn:http://blog.csdn.net/shenshizhong
我的简书:http://www.jianshu.com/u/345daf0211ad

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1087788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

跨语言深入探讨如何实现方法增强:Java Go的多策略实现

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

YB4014是可以对单节磷酸铁锂电池进行恒流/恒压充电管理的集成电路。

概述&#xff1a; YB4014是可以对单节磷酸铁锂电池进行恒流/恒 压充电管理的集成电路。该器件内部包括功率晶 体管&#xff0c;不需要外部的电流检测电阻和阻流二极管 YB4014只需要极少的外围元器件&#xff0c;非常适合于 便携式应用的领域。热调制电路可以在器件的功 耗比较大…

基于SSM的在线教育平台的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

用获取手机号归属地详情,精准高效的API接口服务为标题

获取企业联系人网站API接口是一种非常有用的工具&#xff0c;它可以帮助我们快速获取企业的联系人信息。在这篇博文中&#xff0c;我们将介绍如何使用这个API接口&#xff0c;并讲解其原理和功能。 一、什么是API接口&#xff1f; API是“应用程序编程接口”的缩写&#xff0c…

瑞芯微RK3568核心板在边缘服务器产品中的应用-迅为电子

迅为RK3568核心板在边缘服务器产品中可以发挥关键作用&#xff0c;为边缘计算应用提供高性能的计算和多媒体处理能力。边缘服务器通常用于处理和存储数据&#xff0c;执行本地计算任务&#xff0c;并支持与远程云服务的通信。以下是RK3568核心板在边缘服务器产品中的应用方案&a…

Red Giant Trapcode Suite 红巨星粒子插件

Red Giant Trapcode Suite是一款用于在After Effects中模拟和建模3D粒子和效果的软件&#xff0c;由Red Giant Software公司开发。 该软件包包含11种不同的工具&#xff0c;可以帮助用户模拟火、水、烟、雪等粒子效果&#xff0c;以及创建有机视觉效果和3D元素。它还支持在AE与…

【mysql】 bash: mysql: command not found

在linux 服务器上安装了mysql 也可以正常运行。 但是执行命令&#xff0c;系统提示&#xff1a;bash: mysql: command not found bash:mysql:找不到命令 执行的命令是&#xff1a; mysql -u root -h 127.0.0.1 -p由于系统默认会查找的 /usr/bin/ 中下的命令&#xff0c;如…

Mysql8在Windows上离线安装时忘记root密码

场景 Mysql在Windows上离线安装与配置&#xff1a; Mysql在Windows上离线安装与配置_mysql 离线包 配置 及 自动启动 windows_霸道流氓气质的博客-CSDN博客 基于以上离线安装Msyql后&#xff0c;服务器重新做了系统&#xff0c;但是没有格式化磁盘或者说从 别的服务器将安装…

Jetson Orin NX 开发指南(9): MAVROS 的安装与配置

一、前言 由于 Jetson 系列开发板常作为自主无人机的机载电脑&#xff0c;而无人机硬件平台如 PX4 和 ArduPilot 等通过 MAVLink 进行发布无人机状态和位姿等信息&#xff0c;要实现机载电脑与 MAVLink 的通信&#xff0c;必须借助 Mavros 功能包&#xff0c;因此&#xff0c;…

二叉树的直径

题目链接 二叉树的直径 题目描述 注意点 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 解答思路 最长路径可能经过也可能不经过根节点 root &#xff0c;在遍历至任意节点时&#xff0c;需要找到其左右子树对应的路径&#xff0c;两棵子树的路径之和就是经过该…

严格按照1.5到3倍来设置虚拟内存大小是不科学的,最好通过性能监视器

虚拟内存是一种通过使用硬件和软件来实现的存储器管理技术。它使应用程序认为它有一个连续的可用存储空间或地址空间。然而&#xff0c;事实上&#xff0c;虚拟内存通常被划分为几个物理内存片段&#xff0c;其中一些存储在外部磁盘存储器上&#xff0c;可以在需要时用于交换数…

初学者必看,前端 Debugger 调试学习

1.文章简介&#xff1a; 报错和Bug&#xff0c;是贯穿程序员整个编程生涯中&#xff0c;无法回避的问题。而调试&#xff0c;就是帮助程序员定位问题、解决问题的重要手段&#xff0c;因此调试是每个程序员必备技能。 调试本身可分为两个过程: 定位问题 和 解决问题&#xff0…

[开源]多功能、高效率、低代码的前后端一体化、智能化的开发工具

一、开源项目简介 多功能、高效率、低代码的前后端一体化、智能化的开发工具 mdp-sys-ui-web旨在为企业开发管理类的业务系统提供一个模板工程&#xff0c;该模板工程具有高效率、低代码、功能丰富等特点。企业可以在该工程之上&#xff0c;加入更多其它业务功能&#xff1b;也…

VScode Invoke-Expression: 无法将参数绑定到参数“Command”,因为该参数为空字符串

打开vscode时发生错误&#xff1a;Invoke-Expression : 无法将参数绑定到参数“Command”&#xff0c;因为该参数为空字符串。 解决办法&#xff1a;在anaconda prompt base中输入&#xff1a; conda upgrade -n base -c defaults --override-channels conda

【MultiOTP】Docker安裝MultiOTP, 让Windows登入更安全(MFA)

序 在当前数字时代&#xff0c;网络安全成为了一个非常重要的话题。随着越来越多的人和组织依赖于计算机系统来进行工作和存储敏感信息&#xff0c;确保身份验证安全变得至关重要。双因素身份验证&#xff08;2FA&#xff09;是一种强大的安全措施&#xff0c;可在传统的用户名…

UDP通信:快速入门

UDP协议通信模型演示 UDP API DatagramPacket&#xff1a;数据包对象&#xff08;韭菜盘子&#xff09; public DatagramPacket(byte[] buf, int length, InetAddress address, int port)创建发送端数据包对象 buf&#xff1a;要发送的内容&#xff0c;字节数组 length&…

相似与不同:数字孪生和元宇宙的对比

数字孪生和元宇宙是两个备受瞩目的概念&#xff0c;都在数字领域产生了巨大的影响。它们有一些相似之处&#xff0c;但也存在显著的不同。本文将介绍它们的相同点和不同点&#xff0c;以及它们在不同应用领域的前景。 1. 相同点 虚拟性质&#xff1a; 数字孪生和元宇宙都是虚…

非肿瘤纯生信拿下7+,多种机器学习算法,搭配WGCNA。

今天给同学们分享一篇非肿瘤WGCNA机器学习的生信文章“Screening of immune-related secretory proteins linking chronic kidney disease with calcific aortic valve disease based on comprehensive bioinformatics analysis and machine learning”&#xff0c;这篇文章于2…

Linux:【Kafka四】集群介绍与单机搭建

目录 环境简介 一、搭建kafka集群 1.1、复制出两个kafka的配置文件 1.2、修改配置文件中的如下属性 二、启动kafka集群 三、可校验kafka三个节点是否均启动成功 四、查看集群中主题的分区和副本 4.1、新建一个包含了分区和副本的主题 4.2、查看该主题的详细信息 五、…

有了PMP证书,还用考CSPM吗?

首先结论放前面&#xff08;看个人发展要求&#xff0c;如果想有双证加持的话&#xff0c;建议可以把握这个机会去申请&#xff0c;因为现在处于政策前期&#xff0c;可以免试申请&#xff0c;未来的政策未知。如果目前已经从事项目管理且拥有pmp证书的话&#xff0c;为了以后的…