10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

Agora Flutter SDK:一套代码,实现双端通话(三)

  • 2019-11-30
  • 本文字数:2468 字

    阅读完需:约 8 分钟

Agora Flutter SDK:一套代码,实现双端通话(三)

2 Flutter 和 Native 的交互

我们这里说的 Native 指的是 Android 平台。


那既然要相互通信,就需要将 Flutter 集成到 Android 工程中来,不清楚的如何集成可以看看这里


这里有一点需要注意,就是我们在 Android 代码中需要初始化 Dart VM,不然我们在使用 getFlutterView() 来获取一个 Flutter View 的时候会抛出如下异常:


Caused by: java.lang.IllegalStateException: ensureInitializationComplete must be called after startInitialization        at io.flutter.view.FlutterMain.ensureInitializationComplete(FlutterMain.java:178)...
复制代码


我们有两种方式来执行初始化操作:一个是直接让我们的 Application 继承 FlutterApplication,另外一个是需要我们在我们自己的 Application 中手动初始化:


方法一:


public class App extends FlutterApplication {    }
复制代码


方法二:


public class App extends Application {    @Override    public void onCreate() {    super.onCreate();    // 初始化 Flutter  Flutter.startInitialization(this);    }  }
复制代码


其实方法一中的 FlutterApplication 中在其 onCreate() 方法中干了同样的事情,部分代码如下:


public class FlutterApplication extends Application {
... @CallSuper public void onCreate() { super.onCreate(); FlutterMain.startInitialization(this); } ...}
复制代码


如果我们的 App 只是需要使用 Flutter 在屏幕上绘制 UI,那么没问题, Flutter 框架能够独立完成这些事情。但是在实际的开发中,难免会需要调用 Native 的功能,如:定位,相机,电池等等。这个时候就需要 Flutter 和 Native 通信了。


官网上有一个案例是使用 MethodChannel 来调用给本地的方法获取手机电量。


其实我们还可以使用另外一个类进行通信,叫做 BasicMessageChannel,先来看看它如果创建:


// javabasicMessageChannel = new BasicMessageChannel<String>(getFlutterView(), "foo", StringCodec.INSTANCE);
复制代码


BasicMessageChannel 需要三个参数,第一个是 BinaryMessenger;第二个是通道名称,第三个是交互数据类型的编解码器,我们接下来的例子中的交互数据类型为 String ,所以这里传递的是 StringCodec.INSTANCE,Flutter 中还有其他类型的编解码器 BinaryCodec,JSONMessageCodec 等,他们都有一个共同的父类 MessageCodec。 所以我们也可以根据规则创建自己编解码器。


接下来创建的例子是:Flutter 给 Android 发送一条消息,Android 收到消息之后给 Flutter 回复一条消息,反之亦然。


先来看看 Android 端的部分代码:


// 接收 Flutter 发送的消息
basicMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<String>() { @Override public void onMessage(final String s, final BasicMessageChannel.Reply<String> reply) { // 接收到的消息 linearMessageContainer.addView(buildMessage(s, true)); scrollToBottom(); // 延迟 500ms 回复 flutterContainer.postDelayed(new Runnable() { @Override public void run() { // 回复 Flutter String replyMsg = "Android : " + new Random().nextInt(100); linearMessageContainer.addView(buildMessage(replyMsg, false)); scrollToBottom(); // 回复 reply.reply(replyMsg); } }, 500);
}}); // ---------------------------------------------- // 向 Flutter 发送消息 basicMessageChannel.send(message, new BasicMessageChannel.Reply<String>() { @Override public void reply(final String s) { linearMessageContainer.postDelayed(new Runnable() { @Override public void run() { // Flutter 的回复 linearMessageContainer.addView(buildMessage(s, true)); scrollToBottom(); } }, 500);
} });
复制代码


类似的,Flutter 这边的部分代码如下:


  // 消息通道  static const BasicMessageChannel<String> channel =      BasicMessageChannel<String>('foo', StringCodec());    // ----------------------------------------------
// 接收 Android 发送过来的消息,并且回复 channel.setMessageHandler((String message) async { String replyMessage = 'Flutter: ${Random().nextInt(100)}'; setState(() { // 收到的android 端的消息 _messageWidgets.add(_buildMessageWidget(message, true)); _scrollToBottom(); });
Future.delayed(const Duration(milliseconds: 500), () { setState(() { // 回复给 android 端的消息 _messageWidgets.add(_buildMessageWidget(replyMessage, false)); _scrollToBottom(); }); }); // 回复 return replyMessage; }); // ---------------------------------------------- // 向 Android 发送消息 void _sendMessageToAndroid(String message) { setState(() { _messageWidgets.add(_buildMessageWidget(message, false)); _scrollToBottom(); }); // 向 Android 端发送发送消息并处理 Android 端给的回复 channel.send(message).then((value) { setState(() { _messageWidgets.add(_buildMessageWidget(value, true)); _scrollToBottom(); }); }); }
复制代码


最后的效果如下:屏幕的上半部分为 Android,下半部分为 Flutter



如有问题,欢迎交流,谢谢!


源码地址:


https://github.com/liusilong/FlutterRendering


https://github.com/liusilong/FlutterAndroidCommunicate


本文转载自公众号声网 Agora(ID:shengwang-agora)。


原文链接:


https://mp.weixin.qq.com/s/hawD7myykCkVJbDbpRZHMw


2019-11-30 15:04895

评论

发布
暂无评论
发现更多内容

缓冲区溢出

C语言与CPP编程

c++ C语言 缓冲区 堆栈溢出

闲聊胡扯

C语言与CPP编程

随笔杂谈

Flink检查点存在的性能影响-16

小知识点

scala 大数据 flink

mPaas 厂商push不通排查指南

阿里云金融线TAM SRE专家服务团队

android push

C语言与C++常见面试题

C语言与CPP编程

c++ 面试 C语言

你真的了解 Base64 吗

hepingfly

Java base64 编码

微服务下数据一致性的几种实现方式

xcbeyond

微服务 BASE理论 数据一致性

深挖 Redis 6.0 源码—— SDS

yanglbme

redis 源码 源码分析

终端传感了解吗?18个知识点为你扫盲

华为云开发者联盟

IoT 信息化 传感器 传输协议 无线传输器

Elasticsearch初步认识

枫林

Java elasticsearch ES

Docker 安装和简单使用

枫林

Docker

Docker -快速安装Elasticsearch

枫林

百度被绿了?

程序员生活志

百度 互联网 头条

C/C++函数指针与指针函数

C语言与CPP编程

c++ C语言 函数指针

我们一起学程序-五子棋

叫练

Java 多线程 游戏 websocket

AtmoicXXX与AtmoicXXXArray源码分析

Darren

源码 内存布局 CAS java 并发 AtmoicXXX

最通俗易懂的 Redis 架构模式详解

哈喽沃德先生

redis 架构模式 redis集群 redis哨兵 redis主从

oeasy教您玩转linux010203显示logo

o

在Rust里面嵌入python代码

lipi

Python rust

浮点数比较的精度问题

C语言与CPP编程

c c++

联盟:互联网时代的人才变革

非著名程序员

互联网 个人成长 人才 人才发展 突破圈层,个体崛起

关于MySQL参数,这些你要知道

Simon

MySQL 参数

Pod安装神策SDK报错Remote branch v2.1.3 not found in upstream origin

凌宇之蓝

ios 小程序flutter, 跨平台 CocoaPods pod React Native

《我要进大厂》之mysql夺命连环13问

艾小仙

Java MySQL 面试 Java 分布式 大厂

架构师训练营0期 第十二周作业

WW

面试官问:Spring Boot中Tomcat是怎么启动的

Java小咖秀

tomcat 面试 springboot

再爆安全漏洞,这次轮到Jackson了,竟由阿里云上报

YourBatman

Jackson Fastjson 安全漏洞 CVE-2020-24616

【高并发】要想学好并发编程,关键是要理解这三个核心问题

冰河

写作 多线程 高并发 同步 分工

指针变量的传值和传址

C语言与CPP编程

c++ 指针 C语言

甲方日常 7

句子

工作 随笔杂谈 日常

话题讨论 | 你的桌面上会放哪些有趣的小摆件?

InfoQ写作社区官方

工作 话题讨论 办公室

Agora Flutter SDK:一套代码,实现双端通话(三)_文化 & 方法_声网_InfoQ精选文章