flutter使用Chanel与原生通信
在Flutter中,Platform Channel允许Flutter与原生平台(如Android和iOS)之间进行双向通信,以便在Flutter应用程序和原生代码之间传递消息和调用功能。
以下是使用Platform Channel与原生通信的一般步骤:
1. 在Flutter端创建一个MethodChannel对象,用于发送消息给原生平台。通常在Flutter Widget的初始化方法中创建MethodChannel。
import 'package:flutter/services.dart';// 创建MethodChannel对象
MethodChannel _channel = MethodChannel('com.example.channelName');
2. 在Flutter端发送消息给原生平台,可以使用MethodChannel的invokeMethod方法。
// 发送消息给原生平台
dynamic result = await _channel.invokeMethod('methodName', arguments);
3. 在原生平台(如Android和iOS)实现对应的方法,用于接收Flutter端发送的消息。
对于Android平台,可以在MainActivity或Application类中注册MethodChannel,并实现对应的方法。
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;public class MainActivity extends FlutterActivity {private static final String CHANNEL = "com.example.channelName";@Overridepublic void configureFlutterEngine(FlutterEngine flutterEngine) {super.configureFlutterEngine(flutterEngine);new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL).setMethodCallHandler((call, result) -> {if (call.method.equals("methodName")) {// 处理Flutter端发送的消息String arg = call.arguments.toString();// 执行相应的操作// ...// 将结果返回给Flutter端result.success("Result from native");} else {result.notImplemented();}});}
}
对于iOS平台,在AppDelegate.m文件中注册MethodChannel,并实现对应的方法。
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"@implementation AppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {[GeneratedPluginRegistrant registerWithRegistry:self];FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;FlutterMethodChannel *channel = [FlutterMethodChannelmethodChannelWithName:@"com.example.channelName"binaryMessenger:controller.binaryMessenger];[channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {if ([@"methodName" isEqualToString:call.method]) {// 处理Flutter端发送的消息NSString *arg = call.arguments;// 执行相应的操作// ...// 将结果返回给Flutter端result(@"Result from native");} else {result(FlutterMethodNotImplemented);}}];return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
通过以上步骤,你可以在Flutter端和原生代码之间进行双向通信。
以下是我项目初期的调研代码块:
flutter的代码:
class GetxStatePage extends StatefulWidget {const GetxStatePage({super.key});@overrideState<StatefulWidget> createState() {return GetxStatePageState();}
}class GetxStatePageState extends State<GetxStatePage> {late MethodChannel _channel;@overridevoid initState() {super.initState();//初始化MethodChannel,通道名称“multiple-flutters”,Android端ios也要统一_channel = const MethodChannel('multiple-flutters');}@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(backgroundColor: SGColors.white,title: const Text('Getx',style: TextStyle(color: SGColors.textColor),),),body: Center(child: InkWell(onTap: () {String value = "Hello from Flutter";//这里定义方法和参数_channel.invokeMethod<void>("nextData", {'data': value});// 在此处添加您希望执行的点击事件print('跳转到Android');},child: SizedBox(width: 100,height: 100,child: Text("Getx"),),),),),);}
}
我们再看看Android端的实现代码:首先打通通道需要engine,channel,与flutter端的统一就行;
class EngineBindings(activity: Activity, delegate: EngineBindingsDelegate, entrypoint: String,initialRoute: String) :DataModelObserver {val channel: MethodChannelval engine: FlutterEngineval delegate: EngineBindingsDelegateinit {// This has to be lazy to avoid creation before the FlutterEngineGroup.val dartEntrypoint =DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(), entrypoint)// engine = BaseApplication.getApplication().engines.createAndRunEngine(activity, dartEntrypoint)engine = BaseApplication.getApplication().engines.createAndRunEngine(activity, dartEntrypoint, initialRoute)this.delegate = delegatechannel = MethodChannel(engine.dartExecutor.binaryMessenger, "multiple-flutters")}/*** This setups the messaging connections on the platform channel and the DataModel.*/fun attach() {DataModel.instance.addObserver(this)channel.invokeMethod("setCount", DataModel.instance.counter)channel.setMethodCallHandler { call, result ->when (call.method) {"incrementCount" -> {DataModel.instance.counter = DataModel.instance.counter + 1result.success(null)}"next" -> {this.delegate.onNext()result.success(null)}"nextData" -> {val data: String? = call.argument("data")this.delegate.onNext(data)result.success(null)}else -> {result.notImplemented()}}}}/*** This tears down the messaging connections on the platform channel and the DataModel.*/fun detach() {engine.destroy();DataModel.instance.removeObserver(this)channel.setMethodCallHandler(null)}override fun onCountUpdate(newCount: Int) {channel.invokeMethod("setCount", newCount)}}
具体的activity必须继承FlutterActivity,且这个类必须在主配置清单AndroidMainfest.xml中配置:
<activityandroid:name=".ui.demo.SingleFlutterActivity"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:exported="true"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize" />
class FlutterToAndroidActivity : FlutterActivity(), EngineBindingsDelegate {var mFlutterApi: SGAndroid2Flutter? = nullprivate val engineBindings: EngineBindings by lazy {EngineBindings(activity = this, delegate = this, entrypoint = FlutterRouter.MESSAGE_CENTER_ENTRY_POINTER, initialRoute = "${FlutterRouter.MESSAGE_CENTER_ROUTER}?psId=1234")}override fun onDestroy() {super.onDestroy()engineBindings.detach()}override fun provideFlutterEngine(context: Context): FlutterEngine? {return engineBindings.engine}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)engineBindings.attach()setContentView(layout.activity_flutter_to_android)val extraString = intent.getStringExtra("extraString")tv_center.text = extraStringval binaryMessenger: BinaryMessenger = provideFlutterEngine(this)!!.getDartExecutor().getBinaryMessenger()mFlutterApi = SGAndroid2Flutter(binaryMessenger)tv_center.setOnClickListener {callFlutterMethod()}}private fun callFlutterMethod() {val handler = Handler(Looper.getMainLooper())(0..2).map { it.toLong() * 100 }.forEach {handler.postDelayed(it) {mFlutterApi?.sendData(it.toString()) { // 必须在主线程中调用println("从 Flutter 获取到的值是:$it ") // true,回调在主线程}}}}override fun onNext() {}override fun onNext(str: String?) {}
}
就可以在onNext的方法中调用我们的操作;
/*** flutter 调用原生的方法,原生写法* */override fun onNext(str: String?) {val flutterIntent = Intent(this, FlutterToAndroidActivity::class.java)flutterIntent.putExtra("extraString", str)startActivity(flutterIntent)
}
最后执行,flutter跳转FlutterToAndroidActivity成功,flutter成功调用原生Android的方法。
体会:
之前一直使用纯flutter开发,当需要原生加flutter开发的时候,其实成本更大了。
他既需要Android写好桥接代码,又需要ios写一套,flutter端的是一套。
为什么会这样?因为船大难掉头,一些大的现有项目没办法短时间改技术栈,一些公司会拿出一部分试试水。部分代码迁移。为以后的项目打基础。
遇到些特殊的需求,会更麻烦,比如我们这种做法:需要在原生端获取网络数据,去请求接口,然后把数据传递给flutter,而一开始请求哪个接口,传哪些参数又需要flutter传给原生,Android和ios两端去实现。
所以在项目中我们用到了pigeon的插件,这样就不用写太多的代码,通信的过程pigeon会帮你自动生成,可以看我下一篇文章实践!
https://juejin.cn/post/7270861556031700992
相关文章:
flutter使用Chanel与原生通信
在Flutter中,Platform Channel允许Flutter与原生平台(如Android和iOS)之间进行双向通信,以便在Flutter应用程序和原生代码之间传递消息和调用功能。 以下是使用Platform Channel与原生通信的一般步骤: 1. 在Flutter端…...
Kubernetes技术--k8s核心技术Helm
1.引入 我们先回顾一下之前部署一个应用的过程,如部署nginx,实现效果如下所示: -1.编写deployment的yaml文件,然后运行。 -2.使用service中的NodePort对外暴漏端口 -3.为了弥补Nodeport的缺陷,使用ingress实现转发 这样一个应用就部署完了,这一种情况相对于如果你需要部…...
C/C++学习——单例模式(懒汉模式与饿汉模式)
C/C学习——单例模式 一、什么是单例模式?二、单例模式应用三、单例模式的特点注意:静态成员变量的使用示例代码: 四、单例模式C代码示例(饿汉模式)五、单例模式C示例代码(懒汉模式) 一、什么是…...
企业微信网页开发本地调试方式
一、开启企业微信调试模式 首先在企业微信打开一个网页应用时,其实就是打开了一个微信环境的浏览器,此时想要检查网页元素,查看请求接口,需要开启调试模式。企业微信默认是不支持调试的,需要再单独下载一个文件放在安…...
Prompt GPT推荐社区
大家好,我是荷逸,这次给大家带来的是我日常学习Prompt社区推荐 Snack Prompt 访问地址:http://snackprompt.com Snack Prompt是一个采用的Prompts诱导填空式的社区,它提供了一种简单的prompt修改方式,你只需要输入关…...
小程序隐私保护授权处理方式之弹窗组件
欢迎点击关注-前端面试进阶指南:前端登顶之巅-最全面的前端知识点梳理总结 *分享一个使用比较久的🪜 小程序隐私保护授权弹窗组件 调用wx.getUserProfile进行授权时,返回错误信息:{errMsg: “getUserProfile:fail api scope is…...
Java 复习笔记 - 方法篇
文章目录 一,方法的定义二,最简单的方法定义和调用三,带参数的方法定义和调用四,带返回值方法的定义和调用五,小结六,方法的重载七,方法简单练习1,数组遍历2,数组最大值3…...
大数据到底是好是坏?_光点科技
近年来,随着科技的不断发展和互联网的普及,大数据已经成为一个备受关注的话题。它带来了许多机遇和挑战,引发了人们对于其是好是坏的争议。大数据究竟是一把双刃剑,需要我们从多个角度来审视。 大数据的好处无疑是显而易见的。首先…...
C++ while 循环
只要给定的条件为真,while 循环语句会重复执行一个目标语句。 语法 C 中 while 循环的语法: while(condition) {statement(s); }在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。condition 可以是任意…...
orm_sqlalchemy总结
sqlalchemy使用总结 1 sqlalchemy ORM基础操作 官方文档:https://docs.sqlalchemy.org/en/13/orm/tutorial.html 创建连接 - 创建基类 - 创建实体类 - 创建表 - 创建session import logging import pymysql from pymysql.cursors import DictCursor import sqla…...
CTFhub-文件上传-MIME绕过
用哥斯拉生成 php 木马文件 1.php 抓包---> 修改 conten-type 类型 为 imge/jpeg 用蚁剑连接 ctfhub{8e6af8109ca15932bad4747a}...
【校招VIP】前端校招考点之UDP
考点介绍: UDP是非面向连接协议,使用udp协议通讯并不需要建立连接,它只负责把数据尽可能发送出去,并不可靠,在接收端,UDP把每个消息断放入队列中,接收端程序从队列中读取数据。 『前端校招考点…...
C++设计模式_02_面向对象设计原则
文章目录 1. 面向对象设计,为什么?2. 重新认识面向对象3. 面向对象设计原则3.1 依赖倒置原则(DIP)3.2 开放封闭原则(OCP )3.3 单一职责原则( SRP )3.4 Liskov 替换原则 ( LSP )3.5 接口隔离原则 ( ISP )3.6 优先使用对象组合,而不是类继承3.7…...
springcloud-gateway简述
Spring Cloud Gateway 是一个用于构建 API 网关的项目,它是 Spring Cloud 生态系统中的一部分,旨在为微服务架构提供动态路由、负载均衡、安全性和监控等功能。 网关工程对应pom文件 <?xml version"1.0" encoding"UTF-8"?>…...
【大虾送书第七期】深入浅出SSD:固态存储核心技术、原理与实战
目录 ✨写在前面 ✨内容简介 ✨作者简介 ✨名人推荐 ✨文末福利 🦐博客主页:大虾好吃吗的博客 🦐专栏地址:免费送书活动专栏地址 写在前面 近年来国家大力支持半导体行业,鼓励自主创新,中国SSD技术和产业…...
常见矿石材质鉴定VR实训模拟操作平台提高学员的学习效果和实践能力
随着“元宇宙”概念的不断发展,在矿山领域中,长期存在传统培训内容不够丰富、教学方式单一、资源消耗大等缺点,无法适应当前矿山企业发展需求的长期难题。元宇宙企业借助VR虚拟现实、web3d开发和计算机技术构建的一个虚拟世界,为用…...
Verilog 学习路线
参考知乎 首先得学习数电和 Verilog 基础。 常问的 Verilog 基础 二分频是怎么写的 阻塞和非阻塞及其应用 写一个100MHz的时钟 Reg 和 wire 的区别 Logic 和 wire 的区别,两者可以转换吗 用你最擅长的语言找出1-100的质数 一个最简单的八位加法器应该怎么验…...
前端三剑客中简单的两个:HTMLCSS
HTML&CSS 1,HTML1.1 介绍1.2 快速入门1.3 基础标签1.3.1 标题标签1.3.2 hr标签1.3.3 字体标签 1.4 图片、音频、视频标签1.5 超链接标签1.6 列表标签1.7 表格标签1.8 布局标签1.9 表单标签1.9.1 表单标签概述1.9.2 form标签属性1.9.3 代码演示 1.10 表单项标签 …...
Java实现根据关键词搜索当当商品列表数据方法,当当API接口申请指南
要通过当当网的API获取商品列表数据,您可以使用当当开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例,展示如何通过当当开放平台API获取商品列表: 首先,确保您已注册成为当当开放平台的开发者,并创建…...
【HBZ分享】TCP可靠性传输如何保证的?
ACK机制 ACK机制是发送方与接收方的一个相互确认客户端向服务端发送连接请求,此时服务端要回馈给客户端ACK,以表示服务端接到了客户端请求,这是第一和的第二次握手客户端接收到服务端响应后,同样也要回馈服务端的响应,…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
