目前使用Flutter对APP的部分页面进行改写,在原生基础上展示Flutter页面。其中遇到了打开的Flutter页面(WebView)无法响应H5桥接的问题。
按照网上的方案,WebView和H5的桥接交互主要通过JavascriptChannel实现
WebView(
javascriptChannels: [
_alertJavascriptChannel(context),
].toSet(),
)
JavascriptChannel _alertJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toast',
onMessageReceived: (JavascriptMessage message) {
showToast(message.message);
});
}
但是在我们的项目中使用了WebViewJavascriptBridge进行桥接的封装,所以需要在Flutter端实现WebViewJavascriptBridge的处理逻辑。
iOS有现成的WebViewJavascriptBridge的处理方案,尝试直接搬过来看看能不能跑。
需要理解WebViewJavascriptBridge实现的大致流程,主要是几个时间节点需要对应上:
1.创建桥接对象WebViewJavascriptBridge。这个直接在页面init里面初始化就行了,问题不大
_bridge = WebViewJavascriptBridge();
2.给WebViewJavascriptBridge绑定到一个页面上
iOS是在页面初始化中绑定的,Flutter页面中在WebView的onWebViewCreated绑定是比较合理的
onWebViewCreated: (WebViewController webViewController) {
_webViewController = webViewController;
_bridge.webViewController = _webViewController;
_bridge.messageHandler = null;
registerWebViewJavascriptBridgeHandler();
},
3.WebViewJavascriptBridge注册桥接方法。同上
4.WebViewJavascriptBridge通知前端启动
iOS是在webView:didFinishNavigation:(用的WKNavigationDelegate)回调中执行这一步的,对应WebView的onPageFinished
onPageFinished: (String url) {
print('Page finished loading: $url');
///获取标题
_webViewController.evaluateJavascript("document.title")
.then((result){
print(result);
setState(() {
widget.title = result;
});
});
///WebViewJavascriptBridge桥接相关 通知前端启动
_bridge.webViewPageFinished();
},
5.WebViewJavascriptBridge监听页面发出的桥接请求
iOS是在webView:decidePolicyForNavigationAction:decisionHandler:中实现的,对应WebView的navigationDelegate
navigationDelegate: (NavigationRequest request) {
print('allowing navigation to $request');
String scheme = request.url.split("://")[0]??'';
String host = request.url.split("://")[1]??'';
if(scheme.compareTo('wvjbscheme') == 0) {
if(host.compareTo('__WVJB_QUEUE_MESSAGE__') == 0) {