前言

上一篇我们讲解了如何通过 EventChannel 实现 Android -> Flutter 的通信。

并且也看到了 Flutter 内部 EventChannel 源码也是对 MethodChannel 的封装。

因此这篇我们来说下如何通过 MethodChannel 实现 Android -> Flutter 的通信。

至于 Flutter -> Android 的通信,没看过的小伙伴建议看下之前的文章 Flutter 即学即用系列博客——08 MethodChannel 实现 Flutter 与原生通信。

既然我们之前写过 Flutter -> Android 的 MethodChannel,那么我们现在要写 Android -> Flutter 的 MethodChannel,可以仿照一下原先的写法。

步骤如下:

第一步:Flutter UI 修改

我们的代码在上一篇的基础上做修改,在列上面增加一个文本用于确认收到了 Android 的请求。

String _arguments = 'unknown';
Text(_arguments),

第二步:在 Android 端写 invokeMethod 引用 Flutter 方法

methodChannel.invokeMethod("getContent", "arguments", new MethodChannel.Result() {@Overridepublic void success(@Nullable Object o) {Log.e(TAG, "success="+o);}@Overridepublic void error(String s, @Nullable String s1, @Nullable Object o) {Log.e(TAG, "error="+s);}@Overridepublic void notImplemented() {Log.e(TAG, "notImplemented");}
});

参数说明:
第一个为方法名。用于 Flutter 区分 Android 的不同请求。
第二个为参数值。用于 Android 需要给 Flutter 传递的额外数据。
第三个为 Android -> Flutter 请求的结果回调。
回调有三种情况:
1)调用成功
2)调用失败
3)Flutter 未实现对应方法

第三步:在 Flutter 调用对应 MethodChannel 的 setMethodCallHandler

methodChannel.setMethodCallHandler((MethodCall call){if (call?.method == 'getContent') {setState(() {_arguments = call?.arguments ?? '';});}
});

看到这里的 MethodCall 你应该很熟悉了,通过 call.method 可以知道 Android 要获取的方法名,通过 call.arguments 可以拿到 Android 传递过来的数据。

这里的 getContent 对应 Android 的 invokeMethod。

为了确认我们获取到了,我们将 Android 传递过来的参数显示出来。

第四步:运行

可以看到效果如下:

初始显示 unknown

点击后显示原生传过来的内容

同时控制台显示打印信息如下:

success=null

我们发现 Android 确实回调成功了,但是另一个问题随之而来,Flutter 如何将内容回调给 Android?

解决问题一时爽,一直解决问题一直爽。

也是很简单的,就是我们写一个异步方法将信息带回去即可。

在 setState 方法后面添加下面代码:

return returnToRaw();

具体方法实现如下:

Future<String> returnToRaw() async {return 'received your message';
}

这个时候再运行点击按钮会发现控制台打印如下信息:

success=received your message

可以看到成功收到返回值了。

这里演示返回的是字符串,因此异步方法返回类型是 Future 。如果你要返回其他类型,可以自行修改。

如果希望回调 notImplemented,不要在 Flutter 调用 MethodChannel 的 setMethodCallHandler 或者 setMethodCallHandler 的参数设置为 null 即可。

    //方法一
//    methodChannel.setMethodCallHandler((MethodCall call){
//        if (call?.method == 'getContent') {
//          setState(() {
//            _arguments = call?.arguments ?? '';
//          });
//          return returnToRaw();
//        }
//    });//方法二methodChannel.setMethodCallHandler(null);

如果希望回调 error,修改 returnToRaw 方法即可。如下:

Future<String> returnToRaw() async {throw PlatformException(code: 'error code');
}

这里通过抛出 PlatformException 并将错误信息带回去给 Android。

一般错误信息除非是手动需要抛,否则源码会帮我们处理的。

这里是为了演示所以手动抛出异常。

好了,至此 MethodChannel Android-> Flutter 我们也实现了。

其实不管是 Android -> Flutter 还是 Flutter-> Android,都是平台相关代码。

因此可以直接到 platform_channel.dart 里面看看源码。

除了 EventChannel、MethodChannel,还有 BasicMessageChannel 和 OptionalMethodChannel,这些就交给小伙伴们自己去研究了。

后记

这边分享一下研究 MethodChannel 实现 Android -> Flutter 的过程遇到的坑。

希望不止是授大家以鱼,更是授大家以渔

坑1:一开始将原生 MethodChannel 写到外面,导致 Flutter 没收到请求

因为 Flutter 是在 initState 里面去 setMethodCallHandler 的,而 debug 模式下可能 Flutter 还没加载完成,这个时候发送消息,Flutter 就可能没收到。

后面改成点击之后 Flutter -> Android,Android 再发给 Flutter。

这个问题是异步的原因导致的。

明确之后通过正确的方式就可以收到请求了。

坑2:Flutter 收到之后,如何回调回消息呢?

首先点击进入 setMethodCallHandler 源码,如下:

void setMethodCallHandler(Future<dynamic> handler(MethodCall call)) {BinaryMessages.setMessageHandler(name,handler == null ? null : (ByteData message) => _handleAsMethodCall(message, handler),);
}

再深入 _handleAsMethodCall,如下:

Future<ByteData> _handleAsMethodCall(ByteData message, Future<dynamic> handler(MethodCall call)) async {final MethodCall call = codec.decodeMethodCall(message);try {return codec.encodeSuccessEnvelope(await handler(call));} on PlatformException catch (e) {return codec.encodeErrorEnvelope(code: e.code,message: e.message,details: e.details,);} on MissingPluginException {return null;} catch (e) {return codec.encodeErrorEnvelope(code: 'error', message: e.toString(), details: null);}
}

到这里就比较明朗了。

可以看到错误基本不用我们处理,也没有太多可介入空间。

但是成功回调,这里核心语句是

await handler(call)

因此我们上面通过一个异步方法返回字符串给原生。

由于笔者之前对 Future 不是很熟,因此为了解决这个问题,看了 dart 源码?:
https://www.dartlang.org/tutorials/language/futures

至此,结合系列博客 08 基本就完成了 MethodChannel 相关的双向通信讲解了。

源码位置:
https://github.com/nesger/FlutterSample/tree/feature/method_channel_reverse

更多阅读:
Flutter 即学即用系列博客
Flutter 即学即用系列博客——01 环境搭建
Flutter 即学即用系列博客——02 一个纯 Flutter Demo 说明
Flutter 即学即用系列博客——03 在旧有项目引入 Flutter
Flutter 即学即用系列博客——04 Flutter UI 初窥
Flutter 即学即用系列博客——05 StatelessWidget vs StatefulWidget
Flutter 即学即用系列博客——06 超实用 Widget 集锦
Flutter 即学即用系列博客——07 RenderFlex overflowed 引发的思考
Flutter 即学即用系列博客——08 MethodChannel 实现 Flutter 与原生通信
Flutter 即学即用系列博客——09 EventChannel 实现原生与 Flutter 通信(一)

Flutter & dart
dart 如何优雅的避空
Flutter map 妙用及 .. 使用

转载于:https://www.cnblogs.com/nesger/p/10585045.html

Flutter 即学即用系列博客——09 MethodChannel 实现原生与 Flutter 通信(二)相关推荐

  1. flutter 返回指定界面_Flutter 即学即用系列博客——04 Flutter UI 初窥

    前面三篇可以算是一个小小的里程碑. 主要是介绍了 Flutter 环境的搭建.如何创建 Flutter 项目以及如何在旧有 Android 项目引入 Flutter. 这一篇我们来学习下 Flutte ...

  2. flutter text 自动换行_Flutter 系列博客——05 StatelessWidget vs StatefulWidget

    前言 上一篇我们对 Flutter UI 有了一个基本的了解. 这一篇我们通过自定义 Widget 来了解下如何写一个 Widget? 然而 Widget 有两个,StatelessWidget 和 ...

  3. LINQ之路系列博客后记

    缘起 今年3月,我换了工作单位.后来多次收到公司的新人培训邮件,不过对此我并不感冒,说实话并不喜欢这种活动.印象中,新人培训无非是唠叨些公司的规章制度.侃述一下公司的光辉历史还有灿烂的未来发展等等.规 ...

  4. 堪比培训机构的MySQL系列博客

    这个blog,我整理了我之前写的MySQL开发系列和MySQL运维系列,知识丰富程度堪比培训机构 个人能力有限,如有错误的地方,欢迎指正. 文章目录 一.MySQL开发系列 1.1 MySQL 行转列 ...

  5. Python Web企业门户网站—系列博客教程介绍

    本系列教程将使用Python Web的Django框架实现企业门户网站的制作.本教程一共分为8篇博文,将从最基础的Python语法讲起,然后使用Django3逐步搭建一个完整的企业门户网站项目实例.如 ...

  6. SpringCloud系列博客父工程xml依赖

    SpringCloud系列博客父工程xml依赖 <?xml version="1.0" encoding="UTF-8"?><project ...

  7. 大数据系列博客之 --- 深入简出 Shell 脚本语言(提升篇)

    首先声明,此系列shell系列博客分为四篇发布,分别是: 基础篇:https://www.cnblogs.com/lsy131479/p/9914747.html 提升篇:https://www.cn ...

  8. Django 系列博客(十一)

    Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...

  9. Django 系列博客(二)

    Django 系列博客(二) 前言 今天博客的内容为使用 Django 完成第一个 Django 页面,并进行一些简单页面的搭建和转跳. 命令行搭建 Django 项目 创建纯净虚拟环境 在上一篇博客 ...

最新文章

  1. 2021-2027年中国医疗旅游业投资分析及前景预测报告
  2. Spring----Spring Boot Rest的使用方法
  3. ida提取hashab算法记录
  4. 使用lucce分词怎么_深度学习时代,分词真的有必要吗
  5. 创建Node.js Express 项目
  6. 返回顶部:js代码篇
  7. php大文件读,PHP读取大文件
  8. 【阙值分割】基于matlab粒子群算法自适应多阈值图像分割【含Matlab源码 1459期】
  9. 前端面试宝典-技巧篇
  10. 【学术相关】iccv、cvpr、eccv论文接收率及格式下载(附论文下载)
  11. Hbase中的二级索引
  12. 平面几何常用定理、结论总结 第二篇 微分几何
  13. 三维管型ybc预览以及动态成型仿真控件
  14. 宝宝痰湿体质——家长该如何调理
  15. python处理fasta文件_Python脚本:fasta文件单序列信息提取
  16. 分治算法--L型骨牌棋盘覆盖
  17. 从配置,外观,写一篇小米13测评报告
  18. 网页策略游戏《绝地战争》完整源码下载
  19. delta函数的简化
  20. Intel Chipset Software Installation Utility 9.1.1.1025

热门文章

  1. 《Linux高性能服务器编程》——2.4 IP路由
  2. Spring-IOC
  3. 非官方构建的 Windows 下的 Atom 编辑器
  4. 美国富人如何“逃税”?
  5. python调用摄像头录制视频_Python OpenCV使用摄像头捕获视频
  6. Pytho——装饰器五大实例
  7. python编辑器怎么下载_海龟编辑器(Python编辑器)下载-海龟编辑器(Python编辑器)下载v1.3.6-IE浏览器中文网站...
  8. 滴滴滴,ITester软件测试小栈所有资源放送!
  9. 深度学习中常说的向量和表示
  10. 数据统计作业0429_因子分析/FA