Android PDF 操作 - AndroidPdfViewer 显示 PDF 异常清单(数据为 null、数据为空、PDF 文件损坏、非 PDF 文件)

正常情况

1、Setting
  • settings.gradle
groovy 复制代码
dependencyResolutionManagement {
    
    ...

    repositories {
        
        ...

        maven { url 'https://jitpack.io' }
        maven { url "https://repository.liferay.com/nexus/content/repositories/public/" }
    }
}
  • 模块级 build.gradle
groovy 复制代码
implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1'
2、Activity Layout
xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".viewpdf.ViewPDFActivity">

    <Button
        android:id="@+id/btn_open_pdf"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="打开 PDF 文件"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.github.barteksc.pdfviewer.PDFView
        android:id="@+id/pdfv_container"
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_open_pdf" />
</androidx.constraintlayout.widget.ConstraintLayout>
3、Activity Code
java 复制代码
Button btnOpenPdf = findViewById(R.id.btn_open_pdf);
PDFView pdfvContainer = findViewById(R.id.pdfv_container);

btnOpenPdf.setOnClickListener(v -> {
    File pdfFile = new File(getFilesDir(), "test.pdf");

    InputStream inputStream;
    try {
        inputStream = new FileInputStream(pdfFile);
    } catch (FileNotFoundException e) {
        e.printStackTrace();

        Toast.makeText(this, "PDF 文件不存在", Toast.LENGTH_SHORT).show();

        return;
    }

    pdfvContainer.fromStream(inputStream)
            .enableSwipe(true) // 启用手势滑动翻页
            .swipeHorizontal(false) // 设置滑动方向为垂直滑动
            .enableDoubletap(true) // 启用双击缩放
            .defaultPage(0) // 设置初始显示的页面
            .load();
});

一、数据为 null

1、基本测试
java 复制代码
private byte[] getData() {
    return null;
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .load();
  • 底层报错,应用闪退,输出结果如下

    D Init FPDF library
    java_vm_ext.cc:570] JNI DETECTED ERROR IN APPLICATION: java_array == null
    java_vm_ext.cc:570] in call to GetPrimitiveArray
    java_vm_ext.cc:570] from long com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(byte[], java.lang.String)
    runtime.cc:647] Runtime aborting...
    runtime.cc:647] Dumping all threads without mutator lock held

2、异常捕获测试
java 复制代码
private byte[] getData() {
    return null;
}
java 复制代码
byte[] data = getData();

try {
    pdfvContainer.fromBytes(data)
            .enableSwipe(true) // 启用手势滑动翻页
            .swipeHorizontal(false) // 设置滑动方向为垂直滑动
            .enableDoubletap(true) // 启用双击缩放
            .defaultPage(0) // 设置初始显示的页面
            .load();
} catch (Exception e) {
    e.printStackTrace();
}
  • 异常捕获无效,底层报错,应用闪退,输出结果如下

    D Init FPDF library
    java_vm_ext.cc:570] JNI DETECTED ERROR IN APPLICATION: java_array == null
    java_vm_ext.cc:570] in call to GetPrimitiveArray
    java_vm_ext.cc:570] from long com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(byte[], java.lang.String)
    runtime.cc:647] Runtime aborting...
    runtime.cc:647] Dumping all threads without mutator lock held

3、onError 回调测试
java 复制代码
private byte[] getData() {
    return null;
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .onError(t -> {
            Log.i(TAG, "加载 PDF 失败:" + t.getMessage());
        })
        .load();
  • onError 回调无效,底层报错,应用闪退,输出结果如下

    D Init FPDF library
    java_vm_ext.cc:570] JNI DETECTED ERROR IN APPLICATION: java_array == null
    java_vm_ext.cc:570] in call to GetPrimitiveArray
    java_vm_ext.cc:570] from long com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(byte[], java.lang.String)
    runtime.cc:647] Runtime aborting...
    runtime.cc:647] Dumping all threads without mutator lock held


二、数据为空

1、基本测试
java 复制代码
private byte[] getData() {
    return new byte[0];
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .load();
  • 报错,应用不闪退,异常在库内被捕获,输出结果如下

    load pdf error
    java.io.IOException: cannot create document: File not in PDF format or corrupted.
    at com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(Native Method)
    at com.shockwave.pdfium.PdfiumCore.newDocument(PdfiumCore.java:150)
    at com.github.barteksc.pdfviewer.source.ByteArraySource.createDocument(ByteArraySource.java:35)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:53)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:27)

    复制代码
      ...
2、onError 回调测试
java 复制代码
private byte[] getData() {
    return new byte[0];
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .onError(t -> {
            Log.i(TAG, "加载 PDF 失败:" + t.getMessage());
        })
        .load();
  • onError 回调触发,输出结果如下

    加载 PDF 失败:cannot create document: File not in PDF format or corrupted.


三、数据异常(PDF 文件损坏)

1、基本测试
java 复制代码
private byte[] getData() {
    try {
        File pdfFile = new File(getFilesDir(), "test.pdf");

        InputStream inputStream = new FileInputStream(pdfFile);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        byte[] bytes = buffer.toByteArray();

        // 替换 100 个字节
        for (int i = 0; i < 100; i++) {
            bytes[i] = (byte) (bytes[i] + 1);
        }

        return bytes;
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .load();
  • 报错,应用不闪退,异常在库内被捕获,输出结果如下

    load pdf error
    java.io.IOException: cannot create document: File not in PDF format or corrupted.
    at com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(Native Method)
    at com.shockwave.pdfium.PdfiumCore.newDocument(PdfiumCore.java:150)
    at com.github.barteksc.pdfviewer.source.ByteArraySource.createDocument(ByteArraySource.java:35)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:53)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:27)

    复制代码
      ...
2、onError 回调测试
java 复制代码
private byte[] getData() {
    try {
        File pdfFile = new File(getFilesDir(), "test.pdf");

        InputStream inputStream = new FileInputStream(pdfFile);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        byte[] bytes = buffer.toByteArray();

        // 替换 100 个字节
        for (int i = 0; i < 100; i++) {
            bytes[i] = (byte) (bytes[i] + 1);
        }

        return bytes;
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .onError(t -> {
            Log.i(TAG, "加载 PDF 失败:" + t.getMessage());
        })
        .load();
  • onError 回调触发,输出结果如下

    加载 PDF 失败:cannot create document: File not in PDF format or corrupted.


四、数据异常(非 PDF 文件)

1、基本测试
java 复制代码
private byte[] getData() {
    try {
        File pdfFile = new File(getFilesDir(), "test.docx");

        InputStream inputStream = new FileInputStream(pdfFile);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        return buffer.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .load();
  • 报错,应用不闪退,异常在库内被捕获,输出结果如下

    load pdf error
    java.io.IOException: cannot create document: File not in PDF format or corrupted.
    at com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(Native Method)
    at com.shockwave.pdfium.PdfiumCore.newDocument(PdfiumCore.java:150)
    at com.github.barteksc.pdfviewer.source.ByteArraySource.createDocument(ByteArraySource.java:35)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:53)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:27)

    复制代码
      ...
2、onError 回调测试
java 复制代码
private byte[] getData() {
    try {
        File pdfFile = new File(getFilesDir(), "test.docx");

        InputStream inputStream = new FileInputStream(pdfFile);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        return buffer.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}
java 复制代码
byte[] data = getData();

pdfvContainer.fromBytes(data)
        .enableSwipe(true) // 启用手势滑动翻页
        .swipeHorizontal(false) // 设置滑动方向为垂直滑动
        .enableDoubletap(true) // 启用双击缩放
        .defaultPage(0) // 设置初始显示的页面
        .onError(t -> {
            Log.i(TAG, "加载 PDF 失败:" + t.getMessage());
        })
        .load();
  • onError 回调触发,输出结果如下

    加载 PDF 失败:cannot create document: File not in PDF format or corrupted.

相关推荐
码路飞23 分钟前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
SimonKing1 小时前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员
二流小码农1 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少2 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker2 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋2 小时前
Android 协程时代,Handler 应该退休了吗?
android
Seven972 小时前
剑指offer-80、⼆叉树中和为某⼀值的路径(二)
java
怒放吧德德14 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆15 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
火柴就是我16 小时前
让我们实现一个更好看的内部阴影按钮
android·flutter