使用 evaluateJavascript 处理来自 Android WebView 的 Promise
Posted
技术标签:
【中文标题】使用 evaluateJavascript 处理来自 Android WebView 的 Promise【英文标题】:Handle Promise from Android WebView with evaluateJavascript 【发布时间】:2021-11-10 01:49:39 【问题描述】:我正在使用 android WebView 并尝试在使用 evaluatejavascript 调用 WebView 后处理从 Java 端的 WebView 返回的 JavaScript 承诺。
document.java
Button buttonAnnotations = findViewById(R.id.buttonAnnotations);
buttonAnnotations.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
wv.evaluateJavascript("javascript:getAnnotations();", new ValueCallback<String>()
@Override
public void onReceiveValue(String value)
Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show();
);
);
index.html
async function getAnnotations()
await pdfViewer.getAnnotations().then(result =>
return JSON.stringify(result ,null,2);
);
如果我将 getAnnotations() 函数更改为不是 async 并返回一个字符串一切正常,所以我试图弄清楚如何在 java 代码中处理这个承诺以获取结果。
我见过一些类似的问题,但在这种情况下似乎没有一个答案有效。
【问题讨论】:
这里有什么可用的吗? py4u.net/discuss/643036 JS 代码看起来有点不寻常。如果你声明了一个异步函数,你应该能够在函数中解析 Promise:let result = await pdfViewer.getAnnotations()
。但是getAnnotations
仍然会返回一个 Promise 而不是一个字符串,所以它不会解决你的问题。
【参考方案1】:
正如我在评论中提到的,您正在从异步函数 getAnnotations
(不能直接在 onReceiveValue
中使用)返回一个 Promise。
为了将结果从getAnnotations
“推送”回Android,您必须使用JavascriptInterface
:
在您的活动中,您可以定义:
@JavascriptInterface
public void onAnnotations(String result)
Toast.makeText(WebViewActivity.this, result, Toast.LENGTH_LONG).show();
并通过以下方式注册:
webView.addJavascriptInterface(this, "bridge");
在这种情况下,onAnnotations
方法在包含webView
的 Activity 中抵抗。因此我使用“this”作为第一个参数。
“桥”是命名空间,你可以在其中找到 JavaScript 端的 onAnnotations 函数。
现在您要做的就是从 JavaScript 调用 Android:
function getAnnotations()
pdfViewer.getAnnotations().then(result =>
bridge.onAnnotations(JSON.stringify(result ,null,2));
);
【讨论】:
以上是关于使用 evaluateJavascript 处理来自 Android WebView 的 Promise的主要内容,如果未能解决你的问题,请参考以下文章
使用 EvaluateJavaScript 单击按钮的意外行为
使用 evaluateJavaScript 从 WKWebView 获取标题
WKWebView 中的 Javascript - evaluateJavaScript 与 addUserScript