Android WebView调用evaluateJavascript后如何处理JS返回的Promise结果
问题原因
Android evaluateJavascript 只能获取JS代码执行的同步返回值,你调用的getAnnotations是async函数,默认返回Promise对象,Java侧直接拿到的是"[object Promise]"这类序列化结果,自然无法得到异步执行后的实际返回值。另外你当前的getAnnotations函数没有显式return结果,就算后续处理Promise也会拿到undefined。
解决方案
方案1:通过JavascriptInterface回传结果(最稳定,兼容全版本)
1. Java侧定义JS交互接口
public class JsAnnotationInterface { @JavascriptInterface public void onAnnotationsResult(String result) { // 直接处理返回结果即可 Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show(); } }
2. WebView注册交互接口
在WebView初始化阶段、加载页面前添加配置:
wv.getSettings().setJavaScriptEnabled(true); // 第二个参数是JS侧调用的接口名,可自定义 wv.addJavascriptInterface(new JsAnnotationInterface(), "AndroidAnnotationBridge");
3. 修改JS侧异步函数
异步逻辑执行完成后调用Java侧暴露的接口回传结果:
async function getAnnotations() { const result = await pdfViewer.getAnnotations(); const jsonResult = JSON.stringify(result, null, 2); // 调用Java接口回传数据 AndroidAnnotationBridge.onAnnotationsResult(jsonResult); }
4. Java侧触发执行即可,不需要处理evaluateJavascript的返回回调
wv.evaluateJavascript("javascript:getAnnotations();", null);
方案2:顶层await直接获取Promise结果(无需新增接口,仅支持Android 7.0及以上)
如果不想新增交互接口,可以直接在执行的JS代码块中使用顶层await等待Promise执行完成,直接拿到返回值:
1. 先修正JS侧函数,补充return语句
async function getAnnotations() { // 补充return,把异步结果抛出去 return JSON.stringify(await pdfViewer.getAnnotations(), null, 2); }
2. Java侧调整evaluateJavascript的执行代码
wv.evaluateJavascript("javascript:(async () => { return await getAnnotations(); })();", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { // 注意:evaluateJavascript返回的结果默认会做JSON序列化,比如返回字符串会自动加外层双引号 // 如果需要原始JSON可以做下转义处理: // String realResult = value.substring(1, value.length() - 1).replace("\\\"", "\""); Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show(); } });
注意事项
- 使用JavascriptInterface时注意安全风险,不要暴露敏感操作接口,Android 17及以上必须给接口方法加
@JavascriptInterface注解才能被JS正常调用 - evaluateJavascript的返回值默认会被JSON序列化,处理字符串、JSON类型结果时需要注意转义处理
内容的提问来源于stack exchange,提问作者stonedonkey
相关产品推荐
相关产品推荐

