一、背景
将公司原生项目使用Flutter实现,其中与WebView交互这一块,原生用的是JSBridge,为了避免大量改动,决定Flutter端也采用JSBridge,测试期间发现,在低版本手机,与JS交互方面没问题,但是在高版本手机上,交互全都失效。
二、解决方案
情况一: WebView加载完成之前 无 JS交互
这种情况就比较简单,在该插件的源码中有一个init方法,这个方法就是在执行注入JS的操作。
class JsBridge {
WebViewController _webViewController;
Map<String, CallBackFunction> _callbacks = Map();
Map<String, BridgeHandler> _handlers = Map();
int _uniqueId = 0;
static final String _protocolScheme = "jsbridge://";
final String _fetchData = "${_protocolScheme}return/fetch";
final String _returnData = "${_protocolScheme}return/sendMsg/";
String _dartToJs =
"javascript:WebViewJavascriptBridge._handleMessageFromNative('%s');";
void loadJs(WebViewController controller) {
_webViewController = controller;
init();
}
void init() {
if (_webViewController == null) {
throw "WebViewController must not null";
}
if (Platform.isIOS) {
_loadJs(init_script_ios);
} else {
_loadJs(init_script_android);
}
// test();
}
我们只需要在WebView的状态回调的函数中各进行init一次,保证JS注入是成功的。
WebView(
initialUrl: _web_url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) async {
_jsBridge.loadJs(controller);
_controller.complete(controller);
registerWebViewHandler();
},
navigationDelegate: (NavigationRequest request) {
if (_jsBridge.handlerUrl(request.url)) {
return NavigationDecision.navigate;
}
return NavigationDecision.prevent;
},
onPageStarted: (url) {
_jsBridge.init();
},
onPageFinished:(url) {
_jsBridge.init();
},
onProgress: (value) {
},
);
情况二: WebView加载完成之前 有 JS交互
这种情况一般是在WebView加载完成之前需要传给JS一些数据,目前我没有想到更好的处理方案,只有如下方法暂时处理,如果大家有更好的方案,欢迎在评论区告诉我,感谢!
onProgress: (value) {
if (value > 10) {
_jsBridge.init();
}else if (value > 20){
_jsBridge.init();
}else if (value > 30){
_jsBridge.init();
}else if (value > 40){
_jsBridge.init();
}else if (value > 50){
_jsBridge.init();
}else if (value > 60){
_jsBridge.init();
}else if (value > 70){
_jsBridge.init();
}else if (value > 80){
_jsBridge.init();
}else if (value > 90){
_jsBridge.init();
}
}
这样就能确保在网页加载完成之前注入JS成功,这种挺不严谨的,希望能有更好的解决方案。
网友评论