前言: 在之前经手某一个项目需要用到webview js交互方式, 通过js调用flutter方法,然后同步返回数据给js层. 调研了以下的插件的推荐交互方式均没有这种能力. 然后结合源码以及web控制台的观察, 发现android/ ios 的方式就是给web的window对象注入一个method. 于是我做了以下尝试
现有插件的问题总结
1.以官方的WebView_flutter 插件举例, javascriptChannels的onMessageReceived方法只能做一个单向通信, 也就是说他只能做到JavaScript通过javascriptChannels的name 来postMessage()来调用webview
2.inappwebview 插件也有尝试过 , controller.addJavaScriptHandler确实有callback可以把数据给到JavaScript, 但是文档上说明"window.flutter_inappwebview.callHandler
returns a JavaScript [Promise]" , 也就是说他还是不能同步.
后面我就想有没有办法像android / ios那样直接给window注入method 以及返回值直接给JavaScript来调用呢,于是就调研实验一下_webViewController?.runJavascript()方式
_webViewController?.runJavascript('JavaScript method name(${params})') //实际上我们从文档获取的方法应该这个是一个调用JavaScript 方法的方式
实际上还可以这么用
_webViewController?.runJavascript('window.flutterWebView = {getUserInfo: function() '
'{return${_getAppUserInfoStr()}}}');
//实际上就是给window创建一个flutterWebView对象 , 然后在flutterWebView里创建一个getUserInfo方法 ,然后它返回值是本地的_getAppUserInfoStr(), 它只能支持字符串.
//JavaScript端直接调用就可以获取方法返回值了
window.flutterWebView.getUserInfo
//当然如果实时数据有更新就需要runJavascript重新set一下返回值
//需要注意的是webview的onWebViewCreated里注入会有效, 其他的可能会有时序差异