使用 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 是如何工作的?

使用 EvaluateJavaScript 单击按钮的意外行为

使用 evaluateJavaScript 从 WKWebView 获取标题

WKWebView 中的 Javascript - evaluateJavaScript 与 addUserScript

WKWebView evaluateJavaScript 不返回 html