flutter ios打包_Flutter通过BasicMessageChannel与Android iOS 的双向通信

f9e3ecb0716c82bb8d815ce01df30756.png

更多文章请查看 flutter从入门 到精通

本文章中的完整代码在这里

题记:不到最后时刻,千万别轻言放弃,无论结局成功与否,只要你拼博过,尽力过,一切问心无愧。


通过 Flutter 来进行移动应用开发,打包 Android 、iOS 双平台应用程序,在调用如相机、蓝牙、录音、闹钟、屏保等等系列功能时,需要与原生Android、iOS进行消息通信,或者可描述为把数据由 Flutter 传向 Android 、iOS,或者由原生的 Android 、iOS传向 Flutter。


Flutter 与 Android iOS 原生的通信有以下三种方式

  • BasicMessageChannel 实现 Flutter 与 原生(Android 、iOS)双向通信
  • MethodChannel 实现 Flutter 与 原生原生(Android 、iOS)双向通信
  • EventChannel 实现 原生原生(Android 、iOS)向Flutter 发送消息

本文将实现:(通过 BasicMessageChannel)

  • 实现 Flutter 调用 Android 、iOS 原生的方法并回调Flutter
  • 实现 Flutter 调用 Android 、iOS 原生并打开Android 原生的一个Activity页面,iOS原生的一个ViewController 页面
  • 实现 Android 、iOS 原生主动发送消息到 Flutter 中
  • 实现 Android 、iOS 原生中的 TestActivity 页面主动发送消息到Flutter中

Android 中的效果

b9980914819608b5f5c204b4ccb4b4f2.png


ios 中的效果

5e3a3e639ca95cf115c0f13a327cfbed.png

前言

例如我们要实现 A 调用 B,B就会触发,B再调用A,A就会触发这样的功能,那么我们就需要在 A 中设置 被B调用的监听方法,在B中设置被A 调用的监听方法

1 实现Flutter 调用 Andoid iOS原生方法并回调

在这里约定的数据格式为 {"code":100,"message":"消息","content":内容}也就是说双向发送消息,可能会有多种消息类型来调用不同的功能,统一约定数据格式 可以达到编码的规范性和代码的可维护性

1.1 实现 Flutter 中调用方法

String recive = "";//创建 BasicMessageChannel// flutter_and_native_100 为通信标识// StandardMessageCodec() 为参数传递的 编码方式static const messageChannel = const BasicMessageChannel('flutter_and_native_100', StandardMessageCodec());//发送消息Future<Map> sendMessage(Map arguments) async {Map reply = await messageChannel.send(arguments);//解析 原生发给 Flutter 的参数int code = reply["code"];String message = reply["message"];//更新 Flutter 中页面显示setState(() {recive = "code:$code message:$message";});return reply;}

触发调用 ,分别在 三个 Button 的点击事件中触发

//Flutter 向 Android iOS 中基本的发送消息方式
sendMessage({"method": "test", "ontent": "flutter 中的数据", "code": 100});
//用来实现 Android iOS 主动触发 向 Flutter 中发送消息
sendMessage({"method": "test2", "ontent": "flutter 中的数据", "code": 100});
//用来实现 Flutter 打开 Android iOS 中的一个新的页面
sendMessage({"method": "test3", "ontent": "flutter 中的数据", "code": 100});

1.2 实现实现 Android 中监听方法并回调

Android 的 MainActivity 中注册消息监听

flutter 更新之后 FlutterActivity 中没有 getFlutterView() 方法
使用 getFlutterEngine().getDartExecutor().getBinaryMessenger()代替。
private BasicMessageChannel<Object> mMessageChannel;private void messageChannelFunction() {//消息接收监听//BasicMessageChannel (主要是传递字符串和一些半结构体的数据)//创建通mMessageChannel = new BasicMessageChannel<Object>(getFlutterView(), "flutter_and_native_100", StandardMessageCodec.INSTANCE);// 接收消息监听mMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<Object>() {@Overridepublic void onMessage(Object o, BasicMessageChannel.Reply<Object> reply) {messageController(o,reply);}});}///消息的解析处理privite void messageController(Object o, BasicMessageChannel.Reply<Object> reply){Map<Object, Object> arguments = (Map<Object, Object>) o;//方法名标识String lMethod = (String) arguments.get("method");//测试 reply.reply()方法 发消息给Flutterif (lMethod.equals("test")) {Toast.makeText(mContext, "flutter 调用到了 android test", Toast.LENGTH_SHORT).show();//回调Flutter  Map<String, Object> resultMap = new HashMap<>();resultMap.put("message", "reply.reply 返回给flutter的数据");resultMap.put("code", 200);//回调 此方法只能使用一次 向Flutter中反向回调消息reply.reply(resultMap);} else if (lMethod.equals("test2")) {//测试 mMessageChannel.send 发消息给Flutter//Android 可通过这个方法来主动向 Flutter中发送消息//只有Flutter 中注册了消息监听 才能接收到这个方法向 Flutter 中发送的消息channelSendMessage();} else if (lMethod.equals("test3")) {//测试通过Flutter打开Android ActivityToast.makeText(mContext, "flutter 调用到了 android test3", Toast.LENGTH_SHORT).show();Intent lIntent = new Intent(MainActivity.this, TestBasicMessageActivity.class);MainActivity.this.startActivity(lIntent);}}

1.3 实现实现 iOS 中监听方法 并回调

iOS 的 AppDelegate 中

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import <Flutter/Flutter.h>
//TestViewController 是创建的一个 测试页面
#import "TestViewController.h"@implementation AppDelegate{FlutterBasicMessageChannel* messageChannel;
}- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {[GeneratedPluginRegistrant registerWithRegistry:self];... ... //FlutterBasicMessageChannel 与Flutter 之间的双向通信[self BasicMessageChannelFunction];... ... return [super application:application didFinishLaunchingWithOptions:launchOptions];
}-(void) BasicMessageChannelFunction{//获取当前的 controllerFlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;// 初始化定义// flutter_and_native_100 j messageChannel = [FlutterBasicMessageChannel messageChannelWithName:@"flutter_and_native_100" binaryMessenger:controller];// 接收消息监听[messageChannel setMessageHandler:^(id message, FlutterReply callback) {NSString *method=message[@"method"];if ([method isEqualToString:@"test"]) {NSLog(@"flutter 调用到了 ios test");NSMutableDictionary *dic = [NSMutableDictionary dictionary];[dic setObject:@"[messageChannel setMessageHandler:^(id message, FlutterReply callback)  返回给flutter的数据" forKey:@"message"];[dic setObject: [NSNumber numberWithInt:200] forKey:@"code"];callback(dic);}else  if ([method isEqualToString:@"test2"]) {NSLog(@"flutter 调用到了 ios test2");NSMutableDictionary *dic = [NSMutableDictionary dictionary];[dic setObject:@"[messageChannel sendMessage:dic] 返回给flutter的数据" forKey:@"message"];[dic setObject: [NSNumber numberWithInt:200] forKey:@"code"];//通过这个方法 iOS可以主动多次 向 Flutter 发送消息[messageChannel sendMessage:dic];}else  if ([method isEqualToString:@"test3"]) {NSLog(@"flutter 调用到了 ios test3 打开一个新的页面 ");TestViewController *testController = [[TestViewController alloc]initWithNibName:@"TestViewController" bundle:nil];[controller presentViewController:testController animated:YES completion:nil];}}];}@end

2 Android 、iOS 原生主动发送消息到 Flutter 中

2.1 实现Android 中主动调动调用方法

在MainActivity中,创建了 BasicMessageChannel的实例 mMessageChannel,可以在MainActivity 中直接使用 mMessageChannel 实例来向 Flutter 中发送消息。

private void channelSendMessage() {Toast.makeText(mContext, "flutter 调用到了 android test", Toast.LENGTH_SHORT).show();//构建参数 Map<String, Object> resultMap = new HashMap<>();resultMap.put("message", "reply.reply 返回给flutter的数据");resultMap.put("code", 200);//向 Flutter 中发送消息//参数 二可以再次接收到 Flutter 中的回调//也可以直接使用 mMessageChannel.send(resultMap)mMessageChannel.send(resultMap, new BasicMessageChannel.Reply<Object>() {@Overridepublic void reply(Object o) {Log.d("mMessageChannel", "mMessageChannel send 回调 " + o);}});}

在其他的 Activity 页面中,我们就使用不到这个实例的,我这里的一个实现 Android 中新建的Activity 页面向 Flutter 中发送消息的方法 是广播机制

在 MainActivity 中注册广播,在广播接收者中通过 BasicMessageChannel 的实例 mMessageChannel 来发送消息。
在 Android 中其他的页面中 发送广播到 MainActivity 中的广播接收者中,这样就实现了Android 中新建的Activity 页面向 Flutter 中发送消息

public class MainActivity extends FlutterActivity {... ...Handler mHandler = new Handler(Looper.myLooper());private MainReceiver mMainReceiver;@Overrideprotected void onDestroy() {super.onDestroy();//注销广播unregisterReceiver(mMainReceiver);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);... ...//注册广播mMainReceiver = new MainReceiver();IntentFilter lIntentFilter = new IntentFilter("android.to.flutter");registerReceiver(mMainReceiver, lIntentFilter);}public class MainReceiver extends BroadcastReceiver {public MainReceiver() {}@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "接收到自定义的广播", Toast.LENGTH_SHORT).show();mHandler.post(new Runnable() {@Overridepublic void run() {Map<String, Object> resultMap2 = new HashMap<>();resultMap2.put("message", "android 主动调用 flutter test 方法");resultMap2.put("code", 200);if (mMessageChannel != null) {// 向Flutter 发送消息mMessageChannel.send(resultMap2, new BasicMessageChannel.Reply<Object>() {@Overridepublic void reply(Object o) {System.out.println("android onReply: " + o);}});}}});}}
}

2.2 实现 Flutter 中监听调用方法

//创建 BasicMessageChannel// flutter_and_native_100 为通信标识// StandardMessageCodec() 为参数传递的 编码方式static const messageChannel = const BasicMessageChannel('flutter_and_native_100', StandardMessageCodec());//接收消息监听void receiveMessage() {messageChannel.setMessageHandler((result) async {//解析 原生发给 Flutter 的参数int code = result["code"];String message = result["message"];setState(() {recive = "receiveMessage: code:$code message:$message";});return 'Flutter 已收到消息';});}

2.3 实现 iOS 中主动调动调用方法

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import <Flutter/Flutter.h>
#import "TestViewController.h"@implementation AppDelegate{FlutterBasicMessageChannel* messageChannel;
}- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {[GeneratedPluginRegistrant registerWithRegistry:self];//注册通知[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationFuncion:) name:@"ios.to.flutter" object:nil];... ...return [super application:application didFinishLaunchingWithOptions:launchOptions];
}... ... - (void)notificationFuncion: (NSNotification *) notification {// iOS 中其他页面向Flutter 中发送消息通过这里// 本页中 可以直接使用   [messageChannel sendMessage:dic];//处理消息NSLog(@"notificationFuncion ");NSMutableDictionary *dic = [NSMutableDictionary dictionary];if (messageChannel!=nil) {[dic setObject:@" [messageChannel sendMessage:dic]; 向Flutter 发送消息 " forKey:@"message"];[dic setObject: [NSNumber numberWithInt:401] forKey:@"code"];//主动向Flutter 中发送消息[messageChannel sendMessage:dic];}}- (void)dealloc {//单条移除观察者//[[NSNotificationCenter defaultCenter] removeObserver:self name:@"REFRESH_TABLEVIEW" object:nil];//移除所有观察者[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

ab8712d33b9406575f2ef819d86ba9bc.png

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

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

相关文章

程序员养家活口接私活必备网站(顺便用技术改变世界)

程序员接私活的原因很多种(挣钱、养家糊口、提升技术等等)。下面整理了一下网站送给最有潜能的你。 提前准备好自己的笔记本和技术呦。 1.码客帮:https://www.make8.com/ 码客帮是一个基于众包的互联网软件技术服务平台,建立项目需求方与技术大牛的连接。帮助需求方快速找到靠…

作为服务器上的操作系统,作为服务器的操作系统

作为服务器的操作系统 内容精选换一换本节介绍如何使用华为云镜像&#xff0c;通过切换镜像部署Windows环境。当您已经购买了弹性云服务器&#xff0c;但想切换成其它类型操作系统&#xff0c;或者想使用镜像重新部署已经预装了其它软件的环境&#xff0c;可以参考本文档的介绍…

B.一个人的旅行 (dijkstra算法)

这题实在太醉了。十分简单的一道最短路径。我也wa了几次。最后发现可能是在循环次数n的设置上溢出了。s[1001]最大就1000。。。注意两点之间不止一个路径。上一题畅通工程就被坑惨了。 下面附题目 B - 一个人的旅行Time Limit:1000MS Memory Limit:32768KB 64bit IO Fo…

怎么判断前轮左右的位置_新手开车技巧,确定前轮位置,准确判断与障碍物距离...

今天我们就来学习下&#xff0c;开车时怎样判断前车轮的位置&#xff0c;还有就是怎样判断前车轮与障碍物的距离。我们先进行右轮的判断&#xff0c;首先认识下雨刷器接点位置&#xff0c;雨刷器接点位置&#xff0c;有一定的宽度。当左侧雨刷器的接点&#xff0c;完全和白色实…

安卓的系统设置 位置服务器,修改安卓定位服务器地址

修改安卓定位服务器地址 内容精选换一换状态代码由三位数字组成&#xff0c;第一个数字定义了响应的类别&#xff0c;有五种可能取值&#xff1a;1xx&#xff1a;指示信息&#xff0c;表示请求已接收&#xff0c;继续处理。2xx&#xff1a;成功&#xff0c;表示请求已被成功接收…

[翻译] ABCIntroView

ABCIntroView ABCIntroView is an easy to use onboarding which allows you to introduce your users to the applicaiton before reaching the Main Screen. ABCIntroView是一个简单易用的引导页。 To use the ABCIntroView please do the following: 你需要遵循以下几步来使…

怎样呵护友谊_【家校联动共同呵护孩子健康成长科普课堂】关爱学生心理健康,守护学生健康成长...

健/康/从/心/开/始小学时期是人的行为、性格和智力迅速发展的关键时期。在这一阶段&#xff0c;由于身心变化比较快&#xff0c;加之文化知识及社会经验的不足&#xff0c;小学生很容易产生不健康的心理&#xff0c;导致心理问题或心理疾病。排除小学生认识、情感、意志等方面的…

XML总结

关键词:xml、DTD约束、Schema约束、dom解析、sax解析、jaxp解析器、dom4j解析器 一、xml的简介 1、eXtensible Markup Language:可扩展标记型语言 ①标记型语言:HTML是标记型语言,即使用标签来操作。 ②可扩展: HTML里面的标签是固定,每个标签都有特定的含义<h1><…

中交叉的线_表现力一绝!用交叉线构图拍出来的照片,竟然可以这么吸睛!

不废话&#xff0c;今天为大家介绍一种构图方式&#xff1a;交叉线构图&#xff0c;用这种构图方式拍照&#xff0c;让你的照片表现力一绝&#xff01;1、什么是交叉线构图交叉线构图指的是&#xff0c;在画面中使用交叉线条进行布局的摄影构图方法。看图——↑红色的木桥形成四…

mysql、oracle知识点总结

下面是以前上学那会儿做的笔记,没有好好的整理,凑合着看吧,对新手还是挺有用的 select 标识 选择哪些列. from 标识从哪个表中选择. as 列的别名可以省略,别名使用双引号,可以在别名中包含空格或特殊字符并区分大小写. || 把列与列,列与字符连接在起一起 select ename||_|…

LongAccumulator和DoubleAccumulator类如何工作?

Java 8中的两个新类值得关注&#xff1a; LongAccumulator和DoubleAccumulator 。 它们旨在安全地跨线程安全地累积 &#xff08;稍后将进一步说明&#xff09;。 一个测试值一千个单词&#xff0c;所以它是这样工作的&#xff1a; class AccumulatorSpec extends Specificati…

jQuery 利用 $.getJson() 实现跨域

数据量不大时&#xff0c;跨域的不二之选&#xff0c;而且操作简单&#xff0c;易上手。 a.com/test.html //这里我假定有一些数据&#xff1a; var formData form.serialize(); //这里的jsoncallback 是一个回调函数名 &#xff0c;是必须的参数 //wrand保证每次请求不一样&a…

centos7创建asm磁盘_ASM环境下防止误将数据文件扩容到本地文件系统的方法

前言时常会接到客户或一线工程师反馈oracle数据库报“ora-01110”等错误&#xff0c;本人过往也处理过好几次类似的故障&#xff0c;发现基本上是由于开发人员或初级维护人员在执行数据库表空间扩容时&#xff0c;不小心将本身需要扩容到ASM磁盘组的数据文件扩容到了本地节点上…

前端初级html\css知识点总结

以前的笔记&#xff0c;初级前端知识点&#xff0c;浅显易懂&#xff0c; 一&#xff0c;htmlcss基础 1-1 Html和CSS的关系 学习web前端开发基础技术需要掌握&#xff1a;HTML、CSS、JavaScript语言。下面我们就来了解下这三门技术都是用来实现什么的&#xff1a; 1. HTML是网…

单片机备用电池供电电路_第五节(重排) 电子入门 复位电路

时间有限&#xff0c;无法一一修改底部目录&#xff0c;请以此目录为准&#xff1a;向导&#xff1a;总目录&#xff1a;最好的电子、计算机从入门到工程师教程​zhuanlan.zhihu.com很多看完第三节 电子入门后&#xff0c;感觉难度陡然升高&#xff0c;适应不了&#xff0c;有情…

jQuery插件开发全解析

http://www.iteye.com/topic/545971 jQuery插件的开发包括两种&#xff1a;一种是类级别的插件开发&#xff0c;即给jQuery添加新的全局函数&#xff0c;相当于给jQuery类本身添加方法。jQuery的全局函数就是属于jQuery命名空间的函数&#xff0c;另一种是对象级别的插件开发&a…

jsf 传参数_在JSF 2中对定制验证器进行参数化

jsf 传参数在JSF 2中编写自定义验证器并不是一项复杂的任务。 您实现Validator接口&#xff0c;添加FacesValidator批注&#xff0c;并在faces-config.xml中插入validator声明&#xff0c; 仅此而已 。 一块蛋糕。 但是&#xff0c;让我们考虑以下情形&#xff1a; 您需要自定义…

java应该怎么学习?

很多人刚接触java,比较迷茫,下面我简单梳理一下后端的框架,希望你们能对java有个清晰的认识。 java是一种纯面向对象的编程语言,也是三大编程语言之一。java是由sun公司于1995年开发,它被称为“一次编译,处处可用”。 Struts在项目中的作用 Struts 在项目主要起控制作用…

docker安装clickhouse_clickhouse ----入门

clickhouse作为现在流行的数据分析数据库&#xff0c;非常热门。我也眼馋了好久&#xff0c;想先本地单机安装下&#xff0c;网上搜索了好多。也遇到了好多问题。我这边讲述下自己安装的过程。我这边的电脑是mac.第一步是安装docker.执行命令 brew cask install docker。等dock…

树——平衡二叉树插入和查找的JAVA实现

package com.tomsnail.data.tree; /*** AVL二叉平衡树* author tomsnail* date 2015年3月30日 下午4:35:50*/ public class AVLTree {/*** 根节点* author tomsnail* date 2015年3月30日 下午4:36:54*/private AVLNode rootNode;private String bulidType "";/*** 增…