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,以表示服务端接到了客户端请求,这是第一和的第二次握手客户端接收到服务端响应后,同样也要回馈服务端的响应,…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
