Flutter web bridge 通信总结分析详解
作者:薛定喵的谔 发布时间:2022-05-23 05:15:42
缘起
公司医疗业务人手比较少【小而美】的团队~ 较少采用的前端技术架构是:
toC:小程序 toB2C: Flutter + H5(SPA - React)【build 👉🏻 Android + IOS】 Flutter web + H5 【企业微信服务商应用】
toB: 后台端、 数据大屏 Vue
边缘业务:社区 平台 等 使用的 原生
虽然团队不大但是技术挺杂的,至于为什么要在flutter 中加入 混合开发是因为想通过微架构模式拆分业务,达到资源最大程度的复用;通过 Flutter 解决平台间的复用;微架构的 单页面应用程序解决 业务间的复用。这个暂且不谈,本期整理一下 flutter 中的 bridge 通信;
架构图大致如下 👇🏻
bridge 部分解决各端的
兼容性和平台差异
不同操作系统之间的处理
各端之间跨端通信
第三方 SDK 调用整合
各端业务复用
解决各端之间 Auth 的授权整合
...
通信方式
老生常谈了 其实就是 JS 和 dart 之间的相互调用和注入方法
APP 中 JS & dart call
APP 中
app中主要是通过 webview 来通信和混合开发的方式大同小异;都是 H5 & App 各自注册通过 postmessage | urlchange 来触发调用
主要代码:
通过 Flutter webview中注入 flutter 的方法
Flutter端
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: 'xxBridge',
onMessageReceived: (JavascriptMessage jsMessage) {
Map messageMap = json.decode(jsMessage.message);
print(messageMap);
if (messageMap['type'] == 'appPagePop') {
Navigator.pop(context, messageMap['value']);
return;
}
if (messageMap['type'] == 'navigateTo') {
Map params = messageMap['params'];
String patientCode = params['code'];
Routes.navigateTo(context, messageMap['url'],
params: {'id': UserUtil.transferCodeToId(patientCode)});
return;
}
},
),
].toSet()
H5端
export default class xxBridge {
isApp: boolean;
constructor() {
/**
* receipt app message callback func
* @param message
* @returns boolean
*/
window.flutterMessage = (message: string) => {
console.log(message, ' receipt app message');
return true;
};
}
appPagePop = (value = false) => {
if (!this.isApp) {
console.log('当前不是app环境,或者没有Bridge 运行时哦 ~ !');
window.history.back();
return;
}
window.xxBridge.postMessage(
JSON.stringify({
type: 'appPagePop',
value: value,
}),
);
};
}
Flutter 中调用 H5 在window 注册的方法
onPageFinished: (url) {
print(url + '加载完成');
Map data = {
'doctorCode': UserUtil.doctorCode(),
'doctorName': SpUtil.getString(DOCTOR_NAME_KEY),
};
var dataJson = json.encode(data);
print(dataJson);
_webviewController?.evaluateJavascript("getAppLoginInfo('$dataJson')").then((res) {
print("evaluateJavascript-res: ${res}"); // evaluateJavascript-res: true
});
// print('加载结束');
},
xxBridge
是Flutter JavascriptChannel
注入通信对象onMessageReceived
接收 web端 postmessage 触发 dart 方法web 端中
window.flutterMessage
注册方法给 Flutter 在 app 中调用
至此 Flutter APP 和 H5 通信 基本是以上方式拓展,当然还有 Url 的方式 和 Storage 的方式这里不表;
Flutter web 中 JS & dart call
dart 调用 js
有2种方式
1. Promise js文件的方式被调用
定义方法
function print(msg) {
return new Promise((resolve, reject) => {
resolve('code : xxxxx')
alert(msg)
});
}
调用
import 'dart:js' as js;
@JS()
external print(String msg);
var wxScanPromise = print('123');
String code = await jsUtil.promiseToFuture(wxScanPromise)
2. 通过 js.context 获取上下文来调用
首先在 init 中注入方法
webapp main.dart
class Application {
static Future init(ui.VoidCallback callback) async {
DarttoJS().into();
}
...
}
// This's a test dart to js func
class DarttoJS {
// js call dart
static void myalert(String text) {
Fluttertoast.showToast(
msg: "This's JS pass on test !:$text",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
}
void into() {
js.context["myalert"] = myalert;
js.context.callMethod('onLogin');
}
}
webaapp index 文件中添加 onLogin
const onLogin = () => {
...
}
export { onLogin }
在 init 中注入方法调用类
js.context
来给 js 注入window下的全局方法
js 调用 dart
通过
js.context["myalert"] = myalert
注册了方法直接在js文件中调用
summary
之后我们可以在 xxBridge 中不断的继承 WeChat SDK、dingdingSDK、等等 和一些业务方法 通过 rollup
等一些工具 打包发布NPM包
来源:https://juejin.cn/post/7191835597546209341


猜你喜欢
- Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,是一种比较常用
- 数据库事务是被当作单个工作单元的操作序列。这些操作要么全部完成或全部不成功。事务管理是面向企业应用程序,以确保数据的完整性和一致性RDBMS
- 我们先假设一个场景想象一下,当一个项目出现bug的时候,恰巧这个时候需要你去修改,而当你打开项目之后,眼前的代码让你有一种特别严重的陌生感,
- 今天就是国赛的第一天直接开摆打国赛不如玩羊了个羊玩羊了个羊不如玩MATLAB版写作不易留个赞叭(比赛之余放松一下也行,反正MATLAB版我设
- 目录1.启动分为两种方式2.如何测量一个应用的启动时间3.应用启动的流程4.减少应用的启动时间的耗时5.如何设计延迟加载DelayLoad1
- 对 Debug 的好奇初学 Java 时,我对 IDEA 的 Debug 非常好奇,不止是它能查看断点的上下文环境,更神奇的是我可以在断点处
- (新手写博客,主要是对自己学习的归纳总结。会对很多小细节详解。)单例模式的定义:确保一个类只有一个实例,并提供一个全局访问点。首先实例大家应
- spring-data-redis项目  spring-data-redis提供了在Spring应用中通
- C#正则验证大全 Regex.IsMatch()正则表达式验证需要引入命名空间 using System.Text.RegularExpre
- 分页使用可以说非常普遍了,有时候会需要非常灵活的方式去开启或关闭分页,尝试使用一 * 解的方式来进行分页。依赖安装需要使用的依赖:Mybati
- 在安装过后出现了这样的问题:于是看了一下,是找不到这个版本,于是到gradle文件里加了一句话,指定好版本,切记不要低于26,然后去sdk
- 获取当前键盘按键,代码如下:using UnityEngine;using System.Collections;public class
- AnyChat(全名叫Anychat SDK),也叫音视频互动开发平台;是一套跨平台的即时通讯解决方案,基于先进的H.264视频编码标准、A
- 记事本涉及到的仅仅是对string 的存储,而且在读取上并不存在什么难点,直接用textview显示便可以了。需要做的主要是使用SQLite
- 一、概述一个Process组件提供了在计算机运行进程的访问权限。 进程,在最简单的术语中,是正在运行的应用。提供对本地和远程进程的访问权限并
- 安装Java:安装J2SE开发工具包5.0(JDK 5.0)下载:Java官方网站。请确保以下环境变量设置,如下所述:JAVA_HOME:
- 概述为文档添加必要的批注可以给文档使用者提供重要的提示信息,下面的示例中,将介绍通过C#编程语言来给Excel表格中的指定单元格内容添加批注
- Android ListView的优化,在做Android项目的时候,在用到ListView 界面及数据显示,这个时候如果资源过大,对项目来
- 使用方法 首先在Github或者Gitee上面新建一个仓库复制仓库的链接用idea在本地新建一个demo项目点击菜单栏的VCS,按
- Java Boolean 初始化方式1、Boolean(String boolString);以字符串的方式初始化,只有当字符串是“true