【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

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:04657

评论

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

Spring Boot 项目如何做性能监控?,javase教程书

Java 程序员 后端

Spring--声明式事务控制,mysql索引教程

Java 程序员 后端

springboot文件上传下载实战 ——文件上传,nginx架构模型

Java 程序员 后端

SpringBoot:定制-Actuator,深入java虚拟机百度网盘

Java 程序员 后端

SpringBoot 实现大文件视频转码(转码基于FFMPEG实现)(1)

Java 程序员 后端

SpringBoot2-----异常处理,快手支付中台java面试题

Java 程序员 后端

SpringBoot初始化几大招式,看了终于明白了,Java高级程序员面试集合

Java 程序员 后端

SpringCloud SpringBoot 前后端分离企业级微服务架构源码赠送

Java 程序员 后端

Spring Boot 谷粒学院、谷粒商城项目问题汇总,springboot源码视频

Java 程序员 后端

Spring Boot核心技术之Restful映射以及源码的分析,springboot启动原理通俗

Java 程序员 后端

Spring JdbcTemplate简介,java高级开发面试总结

Java 程序员 后端

SpringBoot-整合HikariCP连接池,java三层架构登录功能实现

Java 程序员 后端

SpringBoot整合MybatisPlus实战动态SQL,linux实用教程文东戈答案

Java 程序员 后端

SpringCloud-Gateway动态路由之Nacos,BATJ等企业Java面试知识分享

Java 程序员 后端

Spring+SpringMVC+MyBatis整合,想拿高工资

Java 程序员 后端

SpringBoot 实现大文件视频转码(转码基于FFMPEG实现)

Java 程序员 后端

SpringCloud 学习总结(思维导图),学习mysql基础教程

Java 程序员 后端

Spring Security账号密码认证源码解析,java项目开发全程实录第四版视频

Java 程序员 后端

spring-boot-route 使用aop记录操作日志,springboot入门项目实战

Java 程序员 后端

Spring Cloud Gateway实战之二:更多路由配置方式,阿里面试java准备

Java 程序员 后端

Spring 基于 xml 配置的快速入门(超详细),数据库事务深入分析

Java 程序员 后端

Spring+MySQL+数据结构,mybatis懒加载的原理及实现

Java 程序员 后端

Springboot实现防重复提交和防重复点击(附源码),java高级编程实验一

Java 程序员 后端

springBoot集成Mybatis,linux系统编程手册pdf百度云

Java 程序员 后端

SpringCloudRPC调用核心原理:RxJava响应式编程框架,观察者模式

Java 程序员 后端

Spring Boot面试题(2020最新版),2021我的Java大厂面试之旅

Java 程序员 后端

springboot 整合 thymeleaf,Java校招面试指南

Java 程序员 后端

Springboot+MybatisPlus高效实现增删改查,mysql使用教程图解目录

Java 程序员 后端

springboot-注解汇总,Java自学宝典下载

Java 程序员 后端

SpringBoot技术实践-SpringRetry重试框架,贼厉害

Java 程序员 后端

SpringBoot自动配置原理及手动实现自动配置,35岁程序员半月4轮面试

Java 程序员 后端

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