Javascript PostMessageAPI可以用于与Android WebView通信吗?
我通常使用HTML5将iframed内容中的信息传递给父框架。最近,我在一个Android WebView中使用了我的内容(据我所知,这是与iframe相当的本地Android版本)。本机应用程序是否有办法监听我发送给他们的PostMessage事件Javascript PostMessageAPI可以用于与Android WebView通信吗?,javascript,android,android-webview,postmessage,Javascript,Android,Android Webview,Postmessage,我通常使用HTML5将iframed内容中的信息传递给父框架。最近,我在一个Android WebView中使用了我的内容(据我所知,这是与iframe相当的本地Android版本)。本机应用程序是否有办法监听我发送给他们的PostMessage事件 我知道这是存在的,我只是希望有一种方法可以重用我现有的PostMessage代码,而不必编写新的东西。您需要使用一个中间抽象接口,在一个实现中通过PostMessage处理消息,在另一个实现中通过addJavascriptInterface处理消息
我知道这是存在的,我只是希望有一种方法可以重用我现有的PostMessage代码,而不必编写新的东西。您需要使用一个中间抽象接口,在一个实现中通过PostMessage处理消息,在另一个实现中通过addJavascriptInterface处理消息
window.addEventListener("message", onReceivedPostMessage, false);
function onReceivedPostMessage(event){
//..ex deconstruct event into action & params
var action = event.data.action;
var params = event.data.params;
performAction(action, params); //performAction would be the uniform API
}
function onReceivedActivityMessageViaJavascriptInterface(json){
//..ex deconstruct data into action & params
var data = JSON.parse(json);
var action = data.action;
var params = data.params;
performAction(action, params); //performAction would be the uniform API
}
我意识到这个问题很老,但我遇到了它,所以我想我会在这里回答。简言之,我发现postMessage至少在从子iframe到父窗口的通信中起作用,但是 事实证明,我们确实不喜欢iframe在android的WebView中的表现方式,所以我们直接呈现了iframe的内容(如您所建议的)。这给我们留下了两个问题——首先,我们有很多从iframe到其父代的消息钩子;其次,我们仍然需要呼叫android对这些事件做出反应 下面是我们代码中的一条示例消息,它散布在整个iframe中:
parent.postMessage(JSON.stringify({
action : 'openModal',
source : embedId
}), '*');
当我们在Android上运行时,我们想要的是在WebView中运行时注入一个对象来处理这个请求
在Android端,这将类似于:
class JsObject {
@JavascriptInterface
public boolean postMessage(String json, String transferList) {
return false; // here we return true if we handled the post.
}
}
// And when initializing the webview...
webView.addJavascriptInterface(new JsObject(), "totDevice");
现在,当运行在此WebViewtotDevice
中时,它将存在,而当运行在iframe中时,它将不存在。因此,现在我们可以创建一个包装器来检查这种情况,并在这两个方法之间切换,而不是直接调用parent.postMessage
。在这里,我们还在Android实现中添加了一个布尔开关,以防您只想处理一些消息:
function postMessage(parent, json, transferlist) {
if (!totDevice || !totDevice.postMessage(json, transferList)) {
parent.postMessage(json, transferlist);
}
}
我们上面的原始postMessage可以重写:
postMessage(parent, JSON.stringify({
action : 'openModal',
source : embedId
}), '*');
现在我们有了一组代码,可以在iframe或androidwebview中运行,而无需更改(至少这部分代码)
我希望这能帮助别人 最近,我们不得不开发一个项目,该项目需要将我们的本地Android应用程序与外部webview进行通信与第三方集成 这个问题在stackoverflow中提出的想法非常有趣,如果您不能触摸该webview的JS代码,则更是如此 我描述了我们如何通过JS通过消息步骤将webview与本机应用程序进行通信 使用我们的webview实现。我们实现该方法是为了注入JS代码来加载web
override fun onPageFinished(url: String?) {
webview.loadUrl(
"javascript:(function() {" +
"window.parent.addEventListener ('message', function(event) {" +
" Android.receiveMessage(JSON.stringify(event.data));});" +
"})()"
)
}
基本上,我们正在做的是创建一个侦听器,将这些消息发送到我们自己的JS和。这是我们之前在Android活动中的webview设置中创建的,与我们通常使用的一样
通过这种方式,我们已经有了通信桥,postMessage发送的所有消息都将通过该侦听器订阅的接口到达我们
class JsObject(val presenter: Presenter) {
@JavascriptInterface
fun receiveMessage(data: String): Boolean {
presenter.onDataReceived(data)
Log.d("Data from JS", data)
return true
}
我也面临着类似的问题,我想听听webview中发生的
.postMessage
事件。我在原始html中签入事件是这样触发的
class JsObject {
@JavascriptInterface
public void receiveMessage(String data) {
Log.i("JsObject", "postMessage data="+data);
//handle data here
}
}
window.parent.postMessage(JSON.stringify(message),'*')代码>
因此,我深入研究了postMessage,找到了添加eventListener的方法
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if (event.origin !== "http://example.org:8080")
return;
// ...
}
帮助我建立
Android JS接口
window.addEventListener("message", onReceivedPostMessage, false);
function onReceivedPostMessage(event){
//..ex deconstruct event into action & params
var action = event.data.action;
var params = event.data.params;
performAction(action, params); //performAction would be the uniform API
}
function onReceivedActivityMessageViaJavascriptInterface(json){
//..ex deconstruct data into action & params
var data = JSON.parse(json);
var action = data.action;
var params = data.params;
performAction(action, params); //performAction would be the uniform API
}
首先是JavascriptInterface的自定义类,如下所示
class JsObject {
@JavascriptInterface
public void receiveMessage(String data) {
Log.i("JsObject", "postMessage data="+data);
//handle data here
}
}
在加载url/html之前将javascriptInterface添加到webview
webView.addJavascriptInterface(new JsObject(), "Android"); //"Android" is just a name
然后在WebViewClient
的onPageStarted
回调中调用javascript,如下所示
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
webView.loadUrl("javascript:(function() {" +
"function receiveMessage(event) {\n" +
"Android.receiveMessage(JSON.stringify(event.data));\n" +
"}" +
"window.addEventListener(\"message\", receiveMessage, false);"+
"})()"
);
Log.i(TAG, "onPageStarted "+url);
}
你解决过这个问题吗?没有,我从来没有解决过,对不起。如果您发现任何问题,请随时添加答案。谢谢您发布此邮件。我已经没有能力再测试这个问题了(自从这个问题发布后,公司发生了变化),但是如果其他人能够确认它对他们有用,我会将它标记为接受。我从来没有从postMessage中得到过这个事件。我需要在webview上设置一些东西来允许这种情况发生吗?@lostintranslation-你可能已经离开很久了,但以防万一有人跟踪。。。您正在使用webView.addJavascriptInterface添加到全局javascript对象。您需要像往常一样注册以侦听消息(例如,window.addEventListener
),然后调用对象-定义该对象上适合处理消息的任何方法。我提供了另一个例子作为替代答案(),并提供了更详细的说明。