求助:Barteksc Android PDFView库无法正确处理损坏/不完整PDF文件
解决Android PDF-Viewer加载损坏PDF显示空白的问题
一、加载前先验证PDF有效性
1. 基础文件校验
先检查文件是否存在、大小是否合理(空文件或极小文件直接判定无效):
if (!pdfFileName.exists() || pdfFileName.length() < 100) { startDownloadActivity(); return; }
2. 校验PDF文件头
PDF标准文件开头是%PDF-,读取前5个字节就能快速判断:
private boolean isPdfHeaderValid(File file) { try (FileInputStream fis = new FileInputStream(file)) { byte[] header = new byte[5]; int readBytes = fis.read(header); return readBytes == 5 && "%PDF-".equals(new String(header)); } catch (IOException e) { return false; } }
3. 深度解析验证(可选)
如果要确保文件能正常解析,可以用iTextG或者系统PdfRenderer做校验:
用iTextG(兼容低版本)
先添加依赖:com.itextpdf:itextg:5.5.10
private boolean isPdfValid(File file) { try (PdfReader reader = new PdfReader(new FileInputStream(file))) { return reader.getNumberOfPages() > 0; } catch (Exception e) { return false; } }
用系统PdfRenderer(API 21+)
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private boolean isPdfValidWithRenderer(File file) { try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); PdfRenderer renderer = new PdfRenderer(fd)) { return renderer.getPageCount() > 0; } catch (IOException e) { return false; } }
二、利用PDF-Viewer的回调捕获加载异常
2.8.2版本的库支持onError和onLoadComplete回调,能直接感知加载状态:
void loadFile(){ // 前置校验 if (!pdfFileName.exists() || !isPdfHeaderValid(pdfFileName) || !isPdfValid(pdfFileName)) { startDownloadActivity(); return; } myPDFViewer.fromFile(pdfFileName) .defaultPage(2) .scrollHandle(new DefaultScrollHandle(this)) .onError(throwable -> startDownloadActivity()) // 加载出错直接跳转 .onLoadComplete(pageCount -> { // 加载完成但页数为0,说明文件损坏 if (pageCount <= 0) { startDownloadActivity(); } }) .load(); } private void startDownloadActivity() { Intent start = new Intent(getApplicationContext(), Downloader.class); start.putExtra("pdfFileName", pdfFileName); startActivity(start); finish(); }
三、注意事项
- 验证PDF的操作尽量放在子线程执行,避免阻塞主线程;
- 如果开启了混淆,要给iTextG添加混淆规则:
-keep class com.itextpdf.** { *; } -dontwarn com.itextpdf.**
内容的提问来源于stack exchange,提问作者md sohan
相关产品推荐
相关产品推荐

