Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript PostMessageAPI可以用于与Android WebView通信吗?_Javascript_Android_Android Webview_Postmessage - Fatal编程技术网

Javascript PostMessageAPI可以用于与Android WebView通信吗?

Javascript PostMessageAPI可以用于与Android WebView通信吗?,javascript,android,android-webview,postmessage,Javascript,Android,Android Webview,Postmessage,我通常使用HTML5将iframed内容中的信息传递给父框架。最近,我在一个Android WebView中使用了我的内容(据我所知,这是与iframe相当的本地Android版本)。本机应用程序是否有办法监听我发送给他们的PostMessage事件 我知道这是存在的,我只是希望有一种方法可以重用我现有的PostMessage代码,而不必编写新的东西。您需要使用一个中间抽象接口,在一个实现中通过PostMessage处理消息,在另一个实现中通过addJavascriptInterface处理消息

我通常使用HTML5将iframed内容中的信息传递给父框架。最近,我在一个Android WebView中使用了我的内容(据我所知,这是与iframe相当的本地Android版本)。本机应用程序是否有办法监听我发送给他们的PostMessage事件


我知道这是存在的,我只是希望有一种方法可以重用我现有的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");
现在,当运行在此WebView
totDevice
中时,它将存在,而当运行在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
),然后调用对象-定义该对象上适合处理消息的任何方法。我提供了另一个例子作为替代答案(),并提供了更详细的说明。