You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android WebView如何显示.js文件(如pdf.js)中的PDF内容?

Android WebView加载Asset内JS存储PDF内容的解决方案

我之前恰好处理过几乎一模一样的场景——当你的Android WebView加载Asset目录里的网页,其他内容都正常,唯独嵌在.js文件(比如pdf.js)里的PDF内容显示不出来,常规的PDF渲染方案完全不适用,因为那些方案都是针对单独的.pdf文件的。结合你给出的具体情况(Asset里有html、fonts、pdf文件夹,用mWebview.loadUrl("file:///android_asset/appFolder/html5/index.html")加载),给你几个实用的解决思路:

1. 先把WebView的基础配置拉满

既然PDF内容是靠JS渲染的,首先得确保WebView给JS足够的运行权限:

  • 必须开启JavaScript:webSettings.setJavaScriptEnabled(true);
  • 开启DOM存储(很多JS驱动的内容依赖这个):webSettings.setDomStorageEnabled(true);
  • 允许访问本地文件:webSettings.setAllowFileAccess(true);
  • 如果你遇到跨域或者本地资源加载的问题,还要加上:webSettings.setAllowUniversalAccessFromFileURLs(true);(注意Android 11+对这个API有调整,需要适配目标版本)

2. 适配JS里的PDF内容渲染逻辑

大多数情况下,JS里的PDF内容要么是base64编码的字符串,要么是二进制数组。你需要确保网页里的JS能正确解析这些数据并调用PDF.js的渲染API:

  • 先检查你的pdf.js文件里的PDF存储格式:如果是base64,要确认WebView的JS引擎支持atob()解码(低版本Android可能需要兼容),可以替换成兼容的解码函数;
  • 如果是二进制数据直接嵌入JS,要把它转换成Blob对象再传给PDF.js。比如你可以在index.html里添加或修改这段逻辑:
// 假设pdfContent是js文件里存储的PDF数据(base64字符串或二进制数组)
let pdfData;
if (typeof pdfContent === 'string') {
  // base64转Uint8Array
  pdfData = Uint8Array.from(atob(pdfContent), c => c.charCodeAt(0));
} else {
  pdfData = pdfContent;
}

// 调用PDF.js渲染到页面的canvas上
pdfjsLib.getDocument({data: pdfData}).promise.then(pdf => {
  return pdf.getPage(1); // 渲染第一页,你可以扩展成多页逻辑
}).then(page => {
  const canvas = document.getElementById('pdf-container');
  const context = canvas.getContext('2d');
  const viewport = page.getViewport({scale: 1.5}); // 调整缩放比例
  canvas.height = viewport.height;
  canvas.width = viewport.width;
  // 渲染页面到canvas
  page.render({
    canvasContext: context,
    viewport: viewport
  });
});
  • 要是你的WebView版本很低(Android 5.0以下),记得引入ES6 API的polyfill,比如Blob、Uint8Array这些的兼容库。

3. 自定义WebViewClient拦截资源加载

有时候WebView会拦截JS里的特殊资源请求,你可以手动处理这些请求,提取JS里的PDF内容并返回正确的资源响应:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        String url = request.getUrl().toString();
        // 这里替换成你识别PDF资源请求的标识,比如URL里的特定参数或路径
        if (url.contains("embedded-pdf-from-js")) {
            try {
                // 从Asset读取pdf.js文件
                InputStream is = getAssets().open("appFolder/html5/js/pdf.js");
                String jsContent = new String(readInputStream(is));
                // 提取JS里的base64格式PDF内容(根据你的实际存储格式调整)
                String pdfBase64 = extractPdfBase64(jsContent);
                // 返回PDF类型的资源响应
                byte[] pdfBytes = Base64.decode(pdfBase64, Base64.DEFAULT);
                return new WebResourceResponse("application/pdf", "UTF-8", new ByteArrayInputStream(pdfBytes));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return super.shouldInterceptRequest(view, request);
    }
});

// 辅助方法:读取输入流为字节数组
private byte[] readInputStream(InputStream is) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    while ((len = is.read(buffer)) != -1) {
        baos.write(buffer, 0, len);
    }
    is.close();
    return baos.toByteArray();
}

// 辅助方法:从JS内容里提取PDF的base64字符串
private String extractPdfBase64(String jsContent) {
    // 示例:假设JS里是var pdfContent = "data:application/pdf;base64,xxxxxx";
    int startMarker = "data:application/pdf;base64,".length();
    int startIndex = jsContent.indexOf("data:application/pdf;base64,") + startMarker;
    int endIndex = jsContent.indexOf("\"", startIndex);
    return jsContent.substring(startIndex, endIndex);
}

这个方法需要你清楚JS里PDF内容的具体存储格式,才能准确提取。

4. 升级WebView或用Chrome Custom Tabs兜底

如果上面的方法都不奏效,可能是系统WebView的JS引擎太老,对PDF.js的支持不足:

  • 可以引导用户升级系统WebView(在应用里提示用户去Google Play更新Chrome/WebView);
  • 或者集成Chrome Custom Tabs,不过要注意Chrome Custom Tabs不能直接访问Asset资源,你需要先把Asset里的网页内容复制到外部存储,再用file://URL加载。

内容的提问来源于stack exchange,提问作者U.A.Hameed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:42:14