如何搭建Android原生应用与WebView间通信桥以获取React应用返回的JSON
你当前代码拿不到JSON的原因是:你在onPageFinished回调中提取的是页面完整DOM结构,此时React已经将API返回的JSON渲染为页面元素,自然无法获取原始JSON响应。下面给出三种可行解决方案:
方案1:可修改React应用代码(推荐,实现成本最低)
直接在React侧拿到API响应后,主动调用你注入的JS接口回传给Android原生即可:
- React端请求成功后新增调用逻辑:
// 你原有发起API请求拿到响应的逻辑 fetch(yourApiUrl, options) .then(res => res.json()) .then(jsonRes => { // 新增这一行,把JSON转为字符串传给Android原生 window.HtmlViewer.showHTML(JSON.stringify(jsonRes)) // 保留你原有渲染JSON到页面的逻辑 })
注意如果JSON内容包含单引号、换行符等特殊字符,需要提前做转义处理,避免JS调用语法报错。
方案2:无法修改React应用代码,原生端拦截API响应
通过重写WebViewClient的shouldInterceptRequest方法,拦截目标API的响应内容,无需前端配合即可拿到原始JSON:
修改你的WebViewClient代码如下:
WebViewClient yourWebClient = new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return false; } @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { // 替换成你要拦截的目标API的地址 String targetApi = "http://your-api-url/xxx"; if (request.getUrl().toString().equals(targetApi)) { try { // 发起请求获取响应 URL url = new URL(request.getUrl().toString()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod(request.getMethod()); // 复制原请求的头信息 for (Map.Entry<String, String> header : request.getRequestHeaders().entrySet()) { conn.setRequestProperty(header.getKey(), header.getValue()); } // 读取响应内容 InputStream inputStream = conn.getInputStream(); // 输入流转字符串也可以自己实现,无需依赖IOUtils String json = new String(IOUtils.toByteArray(inputStream), StandardCharsets.UTF_8); // 这里拿到了原始JSON,做你需要的处理 Log.d("API_JSON", json); // 把响应返回给WebView,不影响页面正常渲染 return new WebResourceResponse( conn.getContentType(), conn.getContentEncoding(), new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)) ); } catch (Exception e) { e.printStackTrace(); } } return super.shouldInterceptRequest(view, request); } @Override public void onPageFinished(WebView view, String url) { // 原有提取HTML的逻辑如果不需要可以删掉 } };
注意:shouldInterceptRequest运行在子线程,如果你拿到JSON后需要更新UI,要通过Handler切到主线程执行。
方案3:临时测试方案(兼容性差)
如果API返回的JSON是直接以纯文本形式展示在页面中,你也可以修改onPageFinished里的JS逻辑,提取页面纯文本内容而非整个HTML:
wb.loadUrl("javascript:HtmlViewer.showHTML(document.body.innerText);");
该方案仅适合页面结构固定的场景,页面元素变更后就会失效。
内容的提问来源于stack exchange,提问作者dileep ch
相关产品推荐
相关产品推荐

