gpt4 book ai didi

android - 如何使用 WebMessagePort 作为 addJavascriptInterface() 的替代品?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:01:07 25 4
gpt4 key购买 nike

谷歌的 security guidelines对于 Android 应用程序开发人员具有以下内容:

WebViews do not use addJavaScriptInterface() with untrusted content.

On Android M and above, HTML message channels can be used instead.

据我所知,“HTML 消息 channel ”指的是类似 createWebMessageChannel() 的内容, WebMessagePort , WebMessage , 和亲属。

但是,他们没有提供任何示例。他们所做的只是链接到 WhatWG specification ,这个比较不清楚。而且,根据对 createWebMessageChannel 的 Google 搜索,这似乎还没有被广泛使用——我的 blog post describing changes in the Android 6.0 SDK进入前 10 名的搜索结果,我只是顺便提一下。

addJavascriptInterface() 用于允许 WebView 中的 JavaScript 调用使用 WebView 的应用程序提供的 Java 代码。我们如何使用“HTML 消息 channel ”来替代它?

最佳答案

好的,我有这个工作,虽然它有点糟糕。

第 1 步:使用 loadDataWithBaseURL() 填充您的 WebViewloadUrl() 将不起作用,因为 bugs .您需要为 loadDataWithBaseURL() 的第一个参数使用 httphttps URL(或者至少不是 file,因为错误)。稍后您将需要该 URL,因此请保留它(例如,private static final String 值)。

第 2 步:决定何时初始化从 JavaScript 到 Java 的通信。使用 addJavascriptInterface(),这立即可用。然而,使用 WebMessagePort 并不是那么好。特别是,您不能在页面加载之前尝试初始化通信(例如,WebViewClient 上的 onPageFinished())。

第 3 步:在您想要初始化这些通信时,调用 WebView 上的 createWebMessageChannel(),以创建一个 WebMessagePort[]。该数组中的第 0 个元素是通信管道的末端,您可以对其调用 setWebMessageCallback() 以响应从 JavaScript 发送给您的消息。

第 4 步:通过将 WebMessagePort[] 中的第一个元素包装在 WebMessage 中并调用 postWebMessage() 将其传递给 JavaScript > 在 WebView 上。 postWebMessage()Uri 作为第二个参数,并且此 Uri 必须派生自您在步骤 #1 中使用的相同 URL loadDataWithBaseURL() 的基本 URL。

  @TargetApi(Build.VERSION_CODES.M)
private void initPort() {
final WebMessagePort[] channel=wv.createWebMessageChannel();

port=channel[0];
port.setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
@Override
public void onMessage(WebMessagePort port, WebMessage message) {
postLux();
}
});

wv.postWebMessage(new WebMessage("", new WebMessagePort[]{channel[1]}),
Uri.parse(THIS_IS_STUPID));
}

(其中 wvWebViewTHIS_IS_STUPID 是与 loadDataWithBaseURL() 一起使用的 URL)

第 5 步:您的 JavaScript 可以为全局 onmessage 事件分配一个函数,该函数将在调用 postWebMessage() 时调用。您在事件中获得的 ports 数组的第 0 个元素将是通信管道的 JavaScript 端,您可以将其填充到某处的变量中。如果需要,如果 Java 代码将使用 WebMessagePort 发送 future 数据,您可以为该端口分配一个函数给 onmessage

第 6 步:当您想从 JavaScript 向 Java 发送消息时,在第 5 步的端口上调用 postMessage(),该消息将被传送到您注册的回调在步骤 #3 中使用 setWebMessageCallback()

var port;

function pull() {
port.postMessage("ping");
}

onmessage = function (e) {
port = e.ports[0];

port.onmessage = function (f) {
parse(f.data);
}
}

This sample app演示了该技术。它有一个 WebView,可显示基于环境光传感器的当前光照水平。该传感器数据以推送方式(当传感器发生变化)或以拉取方式(用户点击网页上的“Light Level”标签)输入到 WebView 中。此应用在 Android 6.0+ 设备上为这些应用使用 WebMessagePort,但推送选项已被注释掉,因此您可以确认拉取方法正在通过端口工作。我将在即将出版的 my book 中更详细地介绍示例应用程序.

关于android - 如何使用 WebMessagePort 作为 addJavascriptInterface() 的替代品?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41753104/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com