Android允许指定一个Javascript接口作为webview和Android代码之间的桥梁。类似地,iOS提供了UiWebView字符串ByEvaluatingJavaScriptFromString方法,该方法允许与底层webview进行通信。
但问题是,一旦我们构建了flutter web应用程序,并表示我们将其作为安卓中web视图的一部分,那么每当需要进行通信时,我们都应该手动在安卓端和javascript端编写一些代码。
由于编辑从flutter web应用程序构建生成的javascript代码是不切实际的,我们需要一种方法在flutter端建立一个通信通道,该通道将使用上面相同类型的javascript桥与本地端进行通信。这将类似于直接在本机端使用flutter应用程序时的方法通道。
那么,我们如何从flutter内部注入或添加自定义javascript代码,以便在编译js文件时添加它呢?
您可以在android端创建一个webmessage频道(iOS也有类似的功能(。
这里有一个关于如何做到这一点的描述:
如何使用WebMessagePort作为addJavascriptInterface((的替代方案?
javascript端的一个简短设置看起来是这样的——您需要在dart-html:中实现它
const channel = new MessageChannel();
var nativeJsPortOne = channel.port1;
var nativeJsPortTwo = channel.port2;
window.addEventListener('message', function(event) {
if (event.data != 'capturePort') {
nativeJsPortOne.postMessage(event.data)
} else if (event.data == 'capturePort') {
/* The following three lines form Android class 'WebViewCallBackDemo' capture the port and assign it to nativeJsPortTwo
var destPort = arrayOf(nativeToJsPorts[1])
nativeToJsPorts[0].setWebMessageCallback(nativeToJs!!)
WebViewCompat.postWebMessage(webView, WebMessageCompat("capturePort", destPort), Uri.EMPTY) */
if (event.ports[0] != null) {
nativeJsPortTwo = event.ports[0]
}
}
}, false);
nativeJsPortOne.addEventListener('message', function(event) {
alert(event.data);
}, false);
nativeJsPortTwo.addEventListener('message', function(event) {
alert(event.data);
}, false);
nativeJsPortOne.start();
nativeJsPortTwo.start();
在flutter web中的窗口上使用事件监听器进行监听的类似解决方案如下:
window.onMessage.listen((onData) {
print(onData.toString());
MessageEvent messageEvent = onData;
for (Property property in properties) {
if (messageEvent.data["id"] == property.id) {
});
} else if (messageEvent.data["northEastLng"] != null) {
print(messageEvent.data["northEastLat"]);
if (double.parse(messageEvent.data["northEastLat"]) == bounds.northEast.lat && double.parse(messageEvent.data["northEastLng"]) == bounds.northEast.lng){
return;
}
LatLng southWest = new LatLng(double.parse(messageEvent.data["southWestLat"]), double.parse(messageEvent.data["southWestLng"]));
LatLng northEast = new LatLng(double.parse(messageEvent.data["northEastLat"]), double.parse(messageEvent.data["northEastLng"]));
LatLngBounds incomingBounds = new LatLngBounds(southWest, northEast);
if (incomingBounds == bounds) {
return;
}
bounds = incomingBounds;
_propertyListPresenter.filterBounds(bounds);
}
}
});