敞开成长之旅!这是我参与「日新计划 12 月更文应战」的第1天,点击检查活动概况
前沿
作为移动端开发,免不了需求内嵌 H5网页 的需求。在 Flutter 中咱们一般经过官方的 webview_flutter 插件完结 WebView 的加载。webview_flutter 插件是由官方维护,底层经过 WebView / WKWebView 原生组件完结,不管是稳定性仍是可靠性上都有保障。但其在与 H5端 的 JSBridge 调用上却差强人意,现在只支撑 H5端 到 App端 的单向调用,并且还不能直接获取返回值,这大大约束了咱们对于 webview_flutter 插件的运用。
为了处理 webview_flutter 的 JS 调用问题,NativeBridge 插件应运而生。
作用展现
在介绍插件前,咱们先看看集成后的作用:
NativeBridge 插件的长处
- 支撑 H5端 调用 App端 的 JSBridge 办法,并能够 直接获取返回值。
- 支撑 App端 调用 H5端 的 JSBridge 办法,并能够 直接获取返回值。
- 运用简单,集成插件后完结 NativeBridgeImpl 类,即可完结 App端 的 JS调用 才能的支撑。
NativeBridge 的引进
NativeBridge 插件现在支撑2种引进办法:1)本地代码引进 2)Git 依靠
- 本地代码引进。因为插件本身只引进了 webview_flutter 插件,所以能够直接拷贝相关代码到自己的项目即可。
- Git 依靠。现在因为插件还没有发布到 pub ,大家能够先经过 Git 依靠的办法引进。
dependencies:
native_bridge:
git:
url: https://github.com/Fitem/native_bridge.git
NativeBridge 的集成
1. App端。在 App端,插件的运用非常简单,只需求下面 两步 即可完结。
第一步,经过 implements NativeBridgeImpl 类,完结其对应的办法。例如 example 中的 NativeBridgeController 类的完结:
class NativeBridgeController implements NativeBridgeImpl {
NativeBridgeController({required this.controller});
// WebView控制器
final Future<WebViewController> controller;
/// 对应JS调用Function集合
@override
Map<String, Function?> get callMethodMap => {
// 版本号
"getVersionCode": (data) async {
return await AppUtil.getVersion();
},
// 版本称号
"getVersionName": (data) async {
return await AppUtil.getVersion();
},
//是否是App
"isApp": (data) {
return true;
},
//测试获取Web的值
"getWebValue": (data) async {
var isHome = await NativeBridgeHelper.sendMessage(
Message(api: "isHome"), this)
.future ??
false;
AppUtil.show("isHome:$isHome");
return true;
}
};
/// 指定JSChannel称号
@override
String get name => "nativeBridge";
/// 履行JS
@override
void runJavascript(String javaScriptString) {
controller.then((controller) =>
controller.runJavascript("receiveMessage($javaScriptString)"));
}
}
- NativeBridgeController 结构参数传入 WebView 的 Controller 目标,用于 runJavascript 的调用
- name 指定 H5 端生成的 window.nativeBridge 目标称号
- callMethodMap 界说 App端 能够支撑的 JSBridge 办法和调用
第二步,在 WebView 组件中增加 NativeBridge。
//JS履行模式 是否允许JS履行
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: <JavascriptChannel>{
NativeBridge(
controller: _nativeBridgeController =
NativeBridgeController(controller: _controller.future),
)
}
2. H5端。H5端的完结也非常简单,1)引进 jsBridgeHelper.js 文件,2)window 目标增加 *receiveMessage 全局办法用于 App端音讯的接收。
function receiveMessage(jsonStr) {
if(jsonStr != undefined && jsonStr != "") {
let data = JSON.parse(JSON.stringify(jsonStr));
window.jsBridgeHelper.receiveMessage(data);
}
}
NativeBridge 的运用
一、H5端 获取 App端 的值
- 在 App端 的 callMethodMap 中 界说办法称号 和 Function调用,比如获取 App 的版本号:
// 版本号
"getVersionCode": (data) async {
return await AppUtil.getVersion();
}
- 在 H5端 中调用对应办法:
async function getVersionName() {
// 获取 App 的值
let appVersionName = await window.jsBridgeHelper.sendMessage("getVersionName", null);
// 显示
document.getElementById("app_version_name").innerHTML = "app version name : " + appVersionName.toString();
}
展现作用:
二、App端 获取 H5端 的值
- App端 先调用 sendMessage() 办法:
var isHome = await NativeBridgeHelper.sendMessage(
Message(api: "isHome"), _nativeBridgeController,
).future ?? false;
AppUtil.show("isHome:$isHome");
- H5端 在 jsBridgeHelper.js 类中的 receiveMessage() 办法中经过对 message.api 辨认,经过 _postMessage() 办法发送App需求获取的值
receiveMessage(message) {
if (message.callbackId) {
// 经过callbackId 获取对应Promise
const cb = this._popCallback(message.callbackId);
if (cb) { //有值,则直接调用对应函数
cb(message.data);
} else { //没有值,则是App恳求获取值
if (message.api === 'isHome') {
this._postMessage(message.api, true.toString(), message.callbackId)
}
}
}
}
展现作用:
总结
今日首要介绍了 Flutter 中基于 webview_flutter 插件完结 App端 和 H5端 的 JS 互调才能的插件 NativeBridge,以及 NativeBridge 的集成和运用,下一篇将介绍 NativeBridge 插件的完结原理和超时检测机制,感兴趣的同学能够重视文章《NativeBridge:完结原理解析》。