Flutter混合开发架构之Channel

454 阅读3分钟

作者:Young,转自公众号 "黑金之路"

背景:

       Flutter 作为跨平台框架,当涉及到混合开发模式时,会遇到一个场景:Flutter 模块需要访问原生的场景,比如需要使用到定位、原生开发的用户资料等等,那么如何高效、简单的实现原生和 Flutter 的通信就是本篇的内容

目录:

  • Channel 简介

  • 协议的定义

  • 通信的设计

一、Channel 简介

图片

Flutter channel 类结构

(1)BinaryMessenger:Platform 端与 Flutter 端通信的工具

(2)BinaryMessageHandler:消息处理的抽象层

(3)BasicMessage / Method / Event Channel

  • BasicMessageChannel:用于传递字符串和半结构化的信息,可持续通信,收到消息后可以回复此次消息

    例如:

    a)Native 将硬件信息陆续传递到 Flutter

    b)Flutter 将从服务器获取的信息传递给 Native 加工,Native 处理完返回等

  • MethodChannel:一次性通信,如:Flutter 调用 Native 拍照等

  • EventChannel:用于事件型的通信,仅支持 native 到 Flutter 的单向传递,如:电量更新通知

举例我们混合开发的业务场景:

  • Flutter 请求 Native 的用户信息、登录 token、环境变量等基础属性

  • Flutter 通知 Native 打开无线传屏等需要调用 C++ so的功能

  • Flutter 通知打开 Native 之前已经实现的复杂业务模块

  • Native 通知 Flutter 更新某些 UI 状态

结合以上官方提供的三种 Channel 和封装统一通信模块的实际需求,选择采用BasicMessageChannel 作为通信层更为合适。

二、 协议的定义*

本处采用 JSON;大家可自定义,如Protobuffer、自定义协议等

字段含义
path类似host路径,响应的地址,例子:/native/common/log
id请求的唯一标识,用于同一个消息调用的区分
metohd请求方式,request,需要回复数据,observer 不需要消息回应,response,针对request的回复
data数据块

另外,metohd 的定义在调用链的降低了协议的可读性,但相对也会暴露一个问题:需要回复结果的请求怎么处理?但考虑我们实际中需要回包执行结果的业务场景比较少,相对来说选择了协议的可读性对多人的开发的团队收益更高。

如果遇到这种场景怎么解决?答案是采用多次交互实现,即多次协议的交互即可。

举例:

图片

协议定义详细

三、通信的设计

核心:

  • Native 接收到消息后,处理任务不能出现阻塞
  • Native 处理任务需要异步,不能卡主线程,避免出现 ANR
  • 发出的每一个消息,不会因为异常等原因被 “淹没”,确保每一个消息都必须回包

图片

Flutter 业务到 Native 流程设计

(1) Flutter 业务从 Channel 模块发送数据协议

(2) 原生协议处理模块,接收到消息队列

(3) 消息工厂生产消息,输出对应的待处理结构体到待处理队列中

(4) 多线程异步分发给 Native 业务处理模块

(5) 消息超时监控,防止队列阻塞,一个必须回复的任务如果在限定/默认时间未处理完则自动以错误处理回复

(6) 步骤4处理结果切换到子线程存储在结果响应队列

(7) 消息工厂处理响应的结果,输出待回复的结构体

(8) 丢到待回复队列,返回给 Flutter Channel 模块

另外:Native 业务到 Flutter 思路一致