Flutter 与原生通信

Flutter 与原生之间的通信主要基于通道机制,包括 MethodChannel、EventChannel 和 BasicMessageChannel。

  • MethodChannel:用于 Flutter 与原生之间的方法调用,实现双向通信,适合一次性的方法调用并获取返回值,如 Flutter调用原生拍照功能并获取照片路径。
  • EventChannel:主要用于原生向 Flutter 发送数据流,例如原生端将传感器数据实时传递给 Flutter 端。
  • BasicMessageChannel:用于 Flutter 与原生之间传递字符串、二进制数据等基本类型的数据,可进行简单的数据交换。

1. Flutter 调用原生

Flutter 端代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('Flutter 调用原生示例'),),body: Center(child: ElevatedButton(onPressed: () async {const platform = MethodChannel('com.example.flutter_native');try {final String result = await platform.invokeMethod('getNativeMessage');print('原生返回的消息: $result');} on PlatformException catch (e) {print('调用原生方法失败: ${e.message}');}},child: const Text('调用原生方法'),),),),);}
}

在 Flutter 端,创建 MethodChannel 实例,使用 invokeMethod 方法调用原生端的 getNativeMessage 方法,并处理返回结果。

安卓原生端代码(Kotlin)

package com.example.flutter_nativeimport android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannelclass MainActivity : FlutterActivity() {private val CHANNEL = "com.example.flutter_native"override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->if (call.method == "getNativeMessage") {result.success("这是来自安卓原生的消息")} else {result.notImplemented()}}}
}

在安卓端,创建 MethodChannel 实例,设置方法调用处理程序,当接收到 getNativeMessage 方法调用时,返回消息给 Flutter 端。

iOS 原生端代码(Swift)

import Flutter
import UIKit@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet channel = FlutterMethodChannel(name: "com.example.flutter_native", binaryMessenger: controller.binaryMessenger)channel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) inif call.method == "getNativeMessage" {result("这是来自 iOS 原生的消息")} else {result(FlutterMethodNotImplemented)}}GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}

在 iOS 端,创建 FlutterMethodChannel 实例,设置方法调用处理程序,处理 getNativeMessage 方法调用并返回消息给 Flutter 端。

2. 原生调用 Flutter

Flutter 端代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const platform = MethodChannel('com.example.native_flutter');platform.setMethodCallHandler((call) async {if (call.method == "getFlutterMessage") {return "这是来自 Flutter 的消息";}return null;});return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('原生调用 Flutter 示例'),),body: const Center(child: Text('等待原生调用...'),),),);}
}

在 Flutter 端,创建 MethodChannel 实例,使用 setMethodCallHandler 方法设置处理原生调用的回调,当接收到 getFlutterMessage 方法调用时,返回消息给原生端。

安卓原生端代码(Kotlin)

package com.example.native_flutterimport android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannelclass MainActivity : FlutterActivity() {private val CHANNEL = "com.example.native_flutter"override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)channel.invokeMethod("getFlutterMessage", null) { result ->println("Flutter 返回的消息: $result")}}
}

在安卓端,创建 MethodChannel 实例,使用 invokeMethod 方法调用 Flutter 端的 getFlutterMessage 方法,并处理返回结果。

iOS 原生端代码(Swift)

import Flutter
import UIKit@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet channel = FlutterMethodChannel(name: "com.example.native_flutter", binaryMessenger: controller.binaryMessenger)channel.invokeMethod("getFlutterMessage", arguments: nil) { (result) inif let message = result as? String {print("Flutter 返回的消息: \(message)")}}GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}

在 iOS 端,创建 FlutterMethodChannel 实例,使用 invokeMethod 方法调用 Flutter 端的 getFlutterMessage 方法,并处理返回结果。

3. EventChannel和BasicMessageChannel

EventChannel和BasicMessageChannel跟上面MethodChannel大同小异。

EventChannel

Flutter端

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const eventChannel = EventChannel('com.example.event_channel');eventChannel.receiveBroadcastStream().listen((event) {print('接收到原生端的事件: $event');}, onError: (error) {print('接收事件时出错: $error');});return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('EventChannel 示例'),),body: const Center(child: Text('等待原生端发送事件...'),),),);}
}

在 Flutter 端,创建 EventChannel 实例,使用 receiveBroadcastStream 方法接收原生端发送的数据流,并通过 listen 方法监听事件。

安卓端

 package com.example.event_channelimport android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannelclass MainActivity : FlutterActivity() {private val CHANNEL = "com.example.event_channel"override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)EventChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setStreamHandler(object : EventChannel.StreamHandler {private var eventSink: EventChannel.EventSink? = nulloverride fun onListen(arguments: Any?, events: EventChannel.EventSink?) {eventSink = events// 模拟每隔 1 秒发送一个事件val timer = android.os.Handler()val runnable = object : Runnable {var counter = 0override fun run() {eventSink?.success("事件 $counter")counter++timer.postDelayed(this, 1000)}}timer.post(runnable)}override fun onCancel(arguments: Any?) {eventSink = null}})}
}

在安卓端,创建 EventChannel 实例,设置 StreamHandler,在 onListen 方法中模拟每隔 1 秒向 Flutter 端发送一个事件,在 onCancel 方法中取消事件发送。

iOS 原生端代码(Swift)

import Flutter
import UIKit@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet eventChannel = FlutterEventChannel(name: "com.example.event_channel", binaryMessenger: controller.binaryMessenger)eventChannel.setStreamHandler(MyStreamHandler())GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}class MyStreamHandler: NSObject, FlutterStreamHandler {var eventSink: FlutterEventSink?var timer: Timer?func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {eventSink = events// 模拟每隔 1 秒发送一个事件timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ invar counter = 0self?.eventSink?("事件 \(counter)")counter += 1}return nil}func onCancel(withArguments arguments: Any?) -> FlutterError? {timer?.invalidate()timer = nileventSink = nilreturn nil}
}

在 iOS 端,创建 FlutterEventChannel 实例,设置 StreamHandler,在 onListen 方法中模拟每隔 1 秒向 Flutter 端发送一个事件,在 onCancel 方法中取消事件发送。

BasicMessageChannel

BasicMessageChannel 用于 Flutter 与原生之间传递字符串、二进制数据等基本类型的数据,是一种双向通信机制,适用于简单的数据交换场景,比如传递配置信息、状态信息等。双方可以互相发送和接收数据。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const messageChannel = BasicMessageChannel<String>('com.example.message_channel', StringCodec());messageChannel.send('来自 Flutter 的消息').then((reply) {if (reply != null) {print('收到原生端的回复: $reply');}});messageChannel.setMessageHandler((message) async {print('收到原生端的消息: $message');return 'Flutter 已收到消息';});return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('BasicMessageChannel 示例'),),body: const Center(child: Text('进行消息通信...'),),),);}
}

在 Flutter 端,创建 BasicMessageChannel 实例,使用 send 方法向原生端发送消息,并处理原生端的回复;使用 setMessageHandler 方法设置处理原生端发送消息的回调。

安卓原生端代码(Kotlin)

package com.example.message_channelimport android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.StringCodecclass MainActivity : FlutterActivity() {private val CHANNEL = "com.example.message_channel"override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)val messageChannel = BasicMessageChannel<String>(flutterEngine.dartExecutor.binaryMessenger,CHANNEL,StringCodec())messageChannel.send("来自安卓原生的消息") { reply ->if (reply != null) {println("收到 Flutter 的回复: $reply")}}messageChannel.setMessageHandler { message, reply ->println("收到 Flutter 的消息: $message")reply.reply("安卓原生已收到消息")}}
}

在安卓端,创建 BasicMessageChannel 实例,使用 send 方法向 Flutter 端发送消息,并处理 Flutter 端的回复;使用 setMessageHandler 方法设置处理 Flutter 端发送消息的回调。

iOS 原生端代码(Swift)

import Flutter
import UIKit@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet messageChannel = FlutterBasicMessageChannel(name: "com.example.message_channel", binaryMessenger: controller.binaryMessenger, codec: FlutterStringCodec.sharedInstance())messageChannel.sendMessage("来自 iOS 原生的消息") { (reply) inif let replyMessage = reply as? String {print("收到 Flutter 的回复: \(replyMessage)")}}messageChannel.setMessageHandler { (message, reply) inif let message = message as? String {print("收到 Flutter 的消息: \(message)")reply("iOS 原生已收到消息")}}GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}

在 iOS 端,创建 FlutterBasicMessageChannel 实例,使用 sendMessage 方法向 Flutter 端发送消息,并处理 Flutter 端的回复;使用 setMessageHandler 方法设置处理 Flutter 端发送消息的回调。

另外:采用信鸽pigeons三方库通信也是一个不错的选择

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

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

相关文章

前端面试-Vue篇

核心概念 Vue 3的响应式原理与Vue 2有何本质区别&#xff1f;Vue中虚拟DOM的diff算法优化策略有哪些&#xff1f;Vue组件间通信方式有哪些&#xff1f;适用场景分别是什么&#xff1f;Vue的生命周期钩子在Composition API中如何替代&#xff1f;Vue的模板编译过程是怎样的&…

光刻机研发与市场现状分析报告

1. 引言 光刻机&#xff08;Lithography Machine&#xff09;是半导体制造的核心设备&#xff0c;其技术水平和市场供应能力直接影响全球芯片产业的发展。随着人工智能&#xff08;AI&#xff09;、5G、高性能计算&#xff08;HPC&#xff09;和自动驾驶等技术的兴起&#xff0…

Missashe考研日记-day21

Missashe考研日记-day21 1 专业课408 学习时间&#xff1a;4h学习内容&#xff1a; 今天先把昨天学的内容的课后习题做了&#xff0c;整整75道啊&#xff0c;然后学了OS第二章关于CPU调度部分的内容&#xff0c;这第二章太重要了&#xff0c;以至于每一小节的内容都比较多&am…

【玩转全栈】—— Django+vue3+讯飞星火API 实现前端页面实时AI答复

技术栈&#xff1a;vue3 element-plus axios pinia router Django5 websocket 讯飞星火API 本文将实现一个 AI 聊天对话功能&#xff0c;将前端用户输入问题以及之前对话发送给后端&#xff0c;通过 api 访问大模型&#xff0c;返回前端实时对话数据。 调用 讯飞星火API…

广东广州一家IPO资产重组疑点重重,信息披露真实性存疑

作者&#xff1a;Eric 来源&#xff1a;IPO魔女 4月18日&#xff0c;广州瑞立科密汽车电子股份有限公司&#xff08;简称“瑞立科密”&#xff09;将接受深交所主板IPO上会审核。公司保荐机构为中信证券&#xff0c;拟募集资金为15.2162亿元。 瑞立科密过往资产重组疑点重重&a…

银河麒麟(Kylin) - V10 SP1桌面操作系统ARM64编译QT-5.15.12版本

银河麒麟(Kylin) - V10 SP1桌面操作系统ARM64编译QT-5.15.12版本 原因 测试Kylin-Desktop-V10-SP1-General-Release-2303-arm64系统下&#xff0c;编译QT-5.15.12版本已做测试。 测试环境 测试板配置 型号&#xff1a;LM-D2000-NONE-1w-V01-pc_A2150 CPU&#xff1a;飞腾D20…

查看前端项目依赖树型结构关系图的详细方法,涵盖 命令行工具 和 可视化工

以下是查看前端项目依赖树型结构关系图的详细方法&#xff0c;涵盖 命令行工具 和 可视化工具&#xff1a; 一、命令行工具生成依赖树 1. npm # 查看项目依赖树&#xff08;文本形式&#xff09; npm ls# 查看指定包的依赖树 npm ls <package-name># 生成JSON格式的依…

Ollama高并发测试

本文主要来测试一下ollama的高并发能力。 具体配置如下&#xff1a; 一、Ollama默认参数执行 我们打开4个窗口&#xff0c;然后分别让DeepSeek “给我讲一个笑话” &#xff0c;看下不同窗口的答题顺序。 通过答题顺序可以看到&#xff0c;在不进行参数设置时&#xff0c;模…

资源管理与HPA:让Kubernetes应用自动伸缩

引言&#xff1a;从“手动挡”到“自动驾驶” 想象我们驾驶一辆汽车&#xff0c;手动调节油门和换挡不仅费力&#xff0c;还难以应对突发状况。我们的应用服务也一样&#xff0c;在面对突然的流量增长&#xff0c;内存使用暴涨该如何应对。HPA&#xff08;Horizontal Pod Auto…

Windows 下 MongoDB ZIP 版本安装指南

在开发和生产环境中&#xff0c;MongoDB 是一种非常流行的 NoSQL 数据库&#xff0c;以其灵活性和高性能而受到开发者的青睐。对于 Windows 用户来说&#xff0c;MongoDB 提供了多种安装方式&#xff0c;其中 ZIP 版本因其灵活性和轻量级的特点&#xff0c;成为很多开发者的首选…

【Linux网络与网络编程】11.数据链路层mac帧协议ARP协议

前面在介绍网络层时我们提出来过一个问题&#xff1a;主机是怎么把数据交给路由器的&#xff1f;那里我们说这是由数据链路层来做的。 网络上的报文在物理结构上是以mac帧的形式流动的&#xff0c;但在逻辑上是以IP流动的&#xff0c;IP的流动是需要mac帧支持的。 数据链路层解…

多模态思维链AI医疗编程:从计算可持续性到开放域推理的系统性解决方案

多模态思维链AI医疗编程:从计算可持续性到开放域推理的系统性解决方案 医疗AI领域的多模态思维链技术正在重塑临床决策支持、医学影像分析和医疗流程优化的范式。本指南从计算可持续性、错误传播控制、伦理安全防护和通用性扩展四大维度,系统解析医疗大模型落地落地的关键要…

代理模式深度解析

目录 一 静态代理 1.1 优点 1.2 缺点 1.3 适用场景 二 JDK动态代理 1 JDK动态代理的工作原理 1.1 创建代理类 1.2 加载代理类 1.3 实现方法调用 2. Proxy.newProxyInstance() 的核心工作流程 方法签名 工作步骤 3. 代理类的生成与加载 3.1 代理类生成的关键方法 …

Spring Cache与Redis集成原理

一、核心架构图解 #mermaid-svg-aiWGQLhmWx7kOfLz {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-aiWGQLhmWx7kOfLz .error-icon{fill:#552222;}#mermaid-svg-aiWGQLhmWx7kOfLz .error-text{fill:#552222;stroke:#5…

编程技能:调试02,设置断点与删除断点

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏&#xff0c;故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 &#xff08;一&#xff09;WIn32 专栏导航 上一篇&#xff1a;编程技能&#xff1a;调试01&#xff0c;调试介绍 回到目录 下…

flink写doris时的优化

1.概念 doris并不擅长高频、小量数据的导入&#xff1b; 因为doris每一次数据导入都会在be节点上生成数据文件&#xff1b;如果高频导入小量数据&#xff0c;就会在存储层产生大量的小文件&#xff08;必然会影响到后续的查询效率&#xff0c;也会对系统产生更多的compaction…

ElementNotInteractableException原因及解决办法

在自动化测试中,ElementNotInteractableException是一个常见的异常,它通常发生在尝试与网页上的某个元素进行交互(例如点击、输入等操作)时,但由于该元素当前不可交互。这可能由多种原因引起,以下是一些常见的原因及其解决方法: 元素未完全加载 如果尝试与页面上的元素交…

如何从 GitHub 镜像仓库到极狐GitLab?

最近 GitHub 封禁中国用户的事情闹得沸沸扬扬,虽然官方发布的报道说中国用户被限制登录是因为配置错误导致,已经撤回了更新,中国用户已经可以正常使用。但是这就像横在国内开发者和企业头上的“达摩克利斯之剑”。为了避免 GitHub 不可用而带来的影响,国内开发者和企业可以…

服务器安装nacos

1.下载依赖 docker pull nacos/nacos-server:v2.4.3安装 docker run -d --name nacos-server -p 8848:8848 -e MODEstandalone nacos/nacos-server:v2.4.3把nacos中的data 文件和conf 文件copy到自己服务的文件夹 docker cp nacos-server:/home/nacos/data /home/admin1/…

Matter协议暗战:苹果、谷歌、亚马逊的智能家居霸权争夺

原文地址&#xff1a;Matter协议暗战&#xff1a;苹果、谷歌、亚马逊的智能家居霸权争夺 一、Matter 协议&#xff1a;巨头联手打造的 “智能家居联合国” 1.1 从 CHIP 到 Matter&#xff1a;标准统一的十年长跑 智能家居发展多年&#xff0c;却始终被 “孤岛效应” 困扰。各…