Android原生与flutter模块交互

news2024/12/24 0:06:01

Flutter定义了三种不同类型的Channel:
BasicMessageChannel:用于传递字符串和半结构化的信息,持续通信,收到消息后可以回复此次消息,如:Native将遍历到的文件信息陆续传递到Dart,在比如:Flutter将从服务端陆陆续获取到信息交个Native加工,Native处理完返回等;
MethodChannel:用于传递方法调用(method invocation)一次性通信:如Flutter调用Native拍照;
EventChannel: 用于数据流(event streams)的通信,持续通信,收到消息后无法回复此次消息,通过长用于Native向Dart的通信,如:手机电量变化,网络连接变化,陀螺仪,传感器等;
项目当前选择的Channel是BasicMessageChannel作为传输数据的通道。

BasicMessageChannel目前传递数据提供的几种消息类型分别是JSONMessageCodec、StandardMessageCodec、StringCodec、BinaryCodec四种类型。
当前项目选择以JSON格式进行数据传输,所以使用的消息类型是JSONMessageCodec。

JSONMessageCodec在flutter里面可传递的数据类型有5种:
分别是bool,num,String,List,Map
在这里插入图片描述
在这里插入图片描述

在项目中使用 BasicMessageChannel 通道 Flutter向Android原生接收与发送请求,Android原生向Flutter接收与发送请求则如下:

首先Flutter向Android原生交互需要先注册唯一标识,唯一标识两端必须一致,iOS原生也是一样

当前唯一标识 CHANNEL_NAME = "flutter_to_native_json_basic"

项目Flutter端代码,设置 BasicMessageChannel 消息通道的方式:

/// 指定原生端与flutter之间交互的消息通道
late BasicMessageChannel channel;

/// 初始化消息通道
initChannel(Function(String)? toPage) {
  this.toPage = toPage;
  /// 创建 Flutter端和原生端的,相互通信的通道
  channel = const BasicMessageChannel(
      KtNativeConstant.CHANNEL_NAME, JSONMessageCodec());
  // 监听来自 原生端 的消息通道,原生端调用了函数,这个handler函数就会被触发
  channel.setMessageHandler(_handler);
}

/// 监听来自 原生端 的消息通道
/// 原生端调用了函数,这个handler函数就会被触发
Future<dynamic> _handler(dynamic message) async {
  nativeBean = KtNativeBean.formJson(message);
  KtLog.e("nativeBean: key = ${nativeBean?.key}");
  /// 接受参数成功返回0给原生端
  return 0;
}

/// flutter向原生端发送消息
flutterSendNativeData(Map<String, String> map) {
  channel.send(map).then((value) {
    KtLog.d("原生端接收成功的数据 value = $value");
  }).catchError((error) {
    /// 发送消息出现错误异常情况接收回调
    if (error is MissingPluginException) {
      KtLog.e(
          "flutterSendNativeData ---- Error:notImplemented --- 未在原生端找到具体实现函数");
    } else {
      KtLog.e("flutterSendNativeData ---- Error:$error");
    }
  });
}

项目Android原生端代码,设置 BasicMessageChannel 消息通道的方式(原生项目首先需搭建与Flutter通讯的activity):
在 KtFlutterActivity 中 设置:

/**
* 原生端与Flutter交互的实例对象
*/
private var channel: KtJsonBasicMessageChannel? = null

/**
* Flutter activity专属回调,在回调中注册与 Flutter 消息传输通道
* @param flutterEngine 项目 Flutter 引擎
*/
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    // 获取消息通道,并设置 Flutter 引擎
    channel = KtJsonBasicMessageChannel.getInstance(flutterEngine.dartExecutor.binaryMessenger)
    // 原生端通过通道发送数据到 Flutter
    channel?.androidSendFlutterData(
        mutableMapOf(
            "key" to "test key",
            "customData" to hashMapOf<String, Any>(),
            "token" to "test token",
            "epid" to "test epid",
            "appId" to "test appId"
        )
    )
}

原生端项目自定义的 KtJsonBasicMessageChannel 需继承于

BasicMessageChannel.MessageHandler<Any>
class KtJsonBasicMessageChannel private constructor(messenger: BinaryMessenger) : BasicMessageChannel.MessageHandler<Any>

/**
* 项目全局的消息通道
*/
private lateinit var mChannel: BasicMessageChannel<Any>

companion object {
    /**
     * 原生View 在Flutter引擎上注册的唯一标识,在Flutter端使用时必须一样
     */
    val CHANNEL_NAME = "flutter_to_native_json_basic"


    /**
     * 单例对象
     * 使用 @Volatile 关键字确保instance字段的可见性,防止多线程环境下出现指令重排序导致的问题。
     */
    @Volatile
    private var instance: KtJsonBasicMessageChannel? = null


    /**
     * 获取单例对象
     * @param messenger
     * @return
     */
    fun getInstance(messenger: BinaryMessenger): KtJsonBasicMessageChannel {
        // 通过双重检查(Double-Checked)机制,在第一次调用getInstance()时进行加锁,确保只有一个线程能够创建实例。
        return instance ?: synchronized(this) {
            instance ?: KtJsonBasicMessageChannel(messenger).also { instance = it }
        }
    }
}

/**
* 初始化消息通道
* @param messenger
*/
private fun initChannel(messenger: BinaryMessenger) {
    // 创建 Android端和Flutter端的,相互通信的通道,通道名称,两端必须一致
    mChannel = BasicMessageChannel(messenger, CHANNEL_NAME, JSONMessageCodec.INSTANCE)
    // 监听来自 Flutter端 的消息通道,Flutter端调用了函数,这个handler函数就会被触发
    mChannel.setMessageHandler(this)
}

/**
* 监听来自 Flutter端 的消息通道
* @param message   Android端 接收到 Flutter端 发来的 数据对象
* @param reply     Android端 给 Flutter端 执行回调的接口对象
*/
override fun onMessage(message: Any?, reply: BasicMessageChannel.Reply<Any>) {
    // 回调结果对象,获取Flutter端传过来的数据
    val flutterData = KtJsonUtils.fromJson(message.toString(), HashMap::class.java)
    "flutter message = ${message?.toString() ?: ""}".loge()


    // 回调状态接口对象,返回给Flutter端
    reply.reply(message)
}

/**
* Android原生端发送消息至Flutter端
* @param data  需要发送的消息
*/
fun androidSendFlutterData(data: MutableMap<String, Any>) {
    mChannel.send(data) { reply ->
        JqzLogUtils.eTag(AppConstants.LOG_HTTP_INFO_TAG, "从flutter 返回回来的数据 reply : $reply")
    }
}

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

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

相关文章

【Python机器学习系列】建立决策树模型预测小麦品种(案例+源码)

这是我的第314篇原创文章。 一、引言 对于表格数据&#xff0c;一套完整的机器学习建模流程如下&#xff1a; 针对不同的数据集&#xff0c;有些步骤不适用&#xff0c;其中橘红色框为必要步骤&#xff0c;欢迎大家关注翻看我之前的一些相关文章。前面我介绍了机器学习模型的二…

MySQL 9.0 发布了!

从昨晚开始&#xff0c;在DBA群里大家就在讨论MySQL 9.0发布的事情&#xff0c;但是Release Note和官方文档都没有更新&#xff0c;所以今天早上一上班就赶紧瞅了下具体更新了哪些内容&#xff1f; 整体看来&#xff0c;基本没什么创新。下面是9.0新增或废弃的一些特性。 &…

自动批量将阿里云盘文件发布成WordPress文章脚本源码(以RiPro主题为例含付费信息下载地址SEO等自动设置)源码

背景 很多资源下载站&#xff0c;付费资源下载站&#xff0c;付费内容查看等都可以用WordPress站点发布内容&#xff0c;这些站点一般会基于一个主题&#xff0c;付费信息作为文章附属的信息发布&#xff0c;底层存储在WP表里&#xff0c;比如日主题&#xff0c;子比主题等。 …

计算机是如何看到图像的

本节课为「计算机视觉 CV 核心知识」第 4 节&#xff1b; 「AI秘籍」系列课程&#xff1a; 人工智能应用数学基础人工智能Python基础人工智能基础核心知识人工智能BI核心知识人工智能CV核心知识 本文涉及代码&#xff1a;https://github.com/hivandu/AI_Cheats Hi, 大家好。我…

【MySQL备份】Percona XtraBackup压缩备份实战篇

目录 1.前言 2.准备工作 2.1.环境信息 2.2.配置/etc/my.cnf文件 2.3.授予root用户BACKUP_ADMIN权限 2.4.安装qpress 3. 压缩备份 3.1.创建压缩备份 3.2.创建全量备份 3.3.对比两个备份的大小 4.解压备份 5.准备备份 6.备份恢复 ​7.问题分析 8.总结 "实战…

网络连接之队头阻塞!!!

一、什么是队头阻塞 队头阻塞&#xff0c;在网络模型中简单理解就是&#xff0c;对于队列型的请求模型&#xff0c;如HTTP的请求-响应模型、TCP的ACK确认机制&#xff0c;都依赖得到一个具体的响应包&#xff0c;如果收不到这个响应包&#xff0c;那下一个请求就不能发&#x…

太阳辐射系统日光全光谱模拟太阳光模拟器

太阳光模拟器是一种用于评估太阳能电池性能的重要设备。它能够模拟太阳光的特性&#xff0c;通过测试电池的短路电流、开路电压、填充因子和光电转化效率等关键指标&#xff0c;来评估电池的性能优劣。 设备型号&#xff1a;KYF-GC004品牌制造商&#xff1a;科迎法电气太阳光模…

08 docker Registry搭建docker私仓

目录 本地镜像发布流程 1. docker pull registry 下载镜像 2. docker run 运行私有库registry 3. docker commit 构建镜像 4. docker tag 修改新镜像&#xff0c;使之符合私服规范tag 5. 修改配置文件使之支持http 6. curl验证私服库上有什么镜像 7. push推送 pull拉取 …

C# WPF自制批注工具(方便标记重点和演示)

在教学和演示中&#xff0c;我们通常需要对重点进行批注&#xff0c;下载安装第三方工具批注显得很麻烦。本篇使用WPF开发了一个批注工具&#xff0c;工具小巧&#xff0c;功能丰富&#xff0c;非常使用日常免费使用&#xff0c;或者进行再次开发。 自制批注工具具有以下功能特…

构建 Audio Unit 的流程

构建 Audio Unit 的流程 构建 Audio Unit 的流程指定 Audio Unit 的类型创建 Audio Unit设置 Audio Unit 的属性 构建 Audio Unit 的流程 iOS 有一个用于直接处理 audio units 的 API&#xff0c;另一个用于处理 audio processing graphs&#xff0c;可以同时使用这两种 API。…

第十四章 路由器 OSPF 动态路由配置

实验目的 掌握 OSPF 协议的配置方法&#xff1a; 掌握查看通过动态路由协议 OSPF 学习产生的路由&#xff1b; 熟悉广域网线缆的链接方式&#xff1b; 实验背景 假设校园网通过一台三层交换机连到校园网出口路由器上&#xff0c; 路由器再和校园外的另一台路由器连接。…

【C++题解】1456. 淘淘捡西瓜

问题&#xff1a;1456. 淘淘捡西瓜 类型&#xff1a;贪心 题目描述&#xff1a; 地上有一排西瓜&#xff0c;每个西瓜都有自己的重量。淘淘有一个包&#xff0c;包的容量是固定的&#xff0c;淘淘希望尽可能在包里装更多的西瓜&#xff08;当然要装整个的&#xff0c;不能切开…

开放签电子签章,让签字有迹可循

开放签&#xff08;企业版&#xff09;V2.0.5版本上线后&#xff0c;系统支持一键查询电子文件的签署操作记录&#xff0c;支持一键生成详细的签署记录报告&#xff0c;详细请看下图&#xff1a; 1、操作记录详情&#xff1a; 从合同发起、填写、签署、撤销等环节全流程展示操…

创新与增长:eBest完美收官FBIF2024食品创新展

FBIF2024食品创新展今天在上海会展中心圆满落幕。此次大会以食品创新、渠道创新、营销创新及科技创新为主题&#xff0c;为众多参展企业及来宾带来一场蕴含创新思维的盛宴。 为什么要“破卷出新”&#xff1f;如今中国食品品牌面临的最大挑战就是在国内饱和的市场里出爆品&…

CTFHUB-SSRF-Redis协议

本题需要用到&#xff1a; 在线编码网址&#xff1a;https://icyberchef.com/ gopherus工具&#xff1a;https://mp.csdn.net/mp_blog/creation/editor/139440201 开启题目&#xff0c;页面空白 和上一个题FastCGI协议一样&#xff0c;还是使用gopherus攻击redis ./gopheru…

【操作与配置】VSCode配置Python

Python环境配置 可以参见&#xff1a;【操作与配置】Python&#xff1a;CondaPycharm_pycharmconda-CSDN博客 官网下载Python&#xff1a;http://www.python.org/download/官网下载Conda&#xff1a;Miniconda — Anaconda documentation VSCode插件安装 插件安装后需重启V…

端口聚合基础知识

一、什么是端口聚合 端口聚合是将多个物理端口捆绑在一起&#xff0c;形成一个逻辑链路&#xff0c;以实现带宽增加、提高冗余和负载均衡的技术。端口聚合&#xff0c;也称为以太通道&#xff08;Ethernet Channel&#xff09;&#xff0c;主要用于交换机之间的连接。在具有多…

我爱服务器——LVM实战学习

后来呀&#xff0c;天亮之前毕业后踏入服务器领域了。。。。。。 LVM&#xff08;Logical Volume Manager&#xff09;是一个高级的磁盘管理框架&#xff0c;它允许用户将多个物理硬盘组合成一个逻辑卷&#xff0c;从而提供更大的存储空间、更高的灵活性和更好的数据管理能力。…

系统安全与应用

目录 1. 系统账户清理 2. 密码安全性控制 2.1 密码复杂性 2.2 密码时限 3 命令历史查看限制 4. 终端自动注销 5. su权限以及sudo提权 5.1 su权限 5.2 sudo提权 6. 限制更改GRUB引导 7. 网络端口扫描 那天不知道为什么&#xff0c;心血来潮看了一下passwd配置文件&am…

分布式锁的详细解析

分布式锁工具 一、背景 当前问题&#xff1a;项目中会使用到分布式锁用于定时任务、接口幂等性处理&#xff0c;但是分布式锁的实现较简单&#xff0c;会出现执行超时、加解锁失败等场景。分布式锁都有哪些实现&#xff0c;他们的优劣势是什么呢&#xff1f; 二、现有技术 分…