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

如何解决使用PdfBox提取PDF文本时出现的ExceptionInInitialize及空指针异常

问题根源
  • 异步调用逻辑错误:registerForActivityResult的launch方法是异步触发系统文件选择器,调用launch后立刻判断fileUri是否非空时,用户还未选择文件、回调还未执行,fileUri仍为null,后续提取逻辑直接触发空指针。
  • PDFTextStripper类初始化失败:你使用的是Android端适配的PdfBox分支(com.tom_roush.pdfbox),该库初始化PDFTextStripper时需要读取内置的字体配置资源,如果构建配置开启了混淆、资源压缩,或者未正确引入依赖的fontbox组件,就会导致读取资源的InputStream为null,关闭时抛出你日志中显示的<clinit>阶段空指针。
  • 代码空安全处理不到位:document加载失败时为null、inputStream打开失败时为null的场景都没有做拦截处理,会触发后续逻辑空指针。
解决方案

1. 修复异步调用逻辑

将extractTextPdfFile的调用放到registerForActivityResult的回调中,选到文件后再执行提取逻辑,修改后代码:

private var fileUri: Uri? = null
private val getContent =
    registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        // Handle the returned Uri
        if (uri != null) {
            fileUri = uri
            // 选到文件后再调用提取逻辑
            extractTextPdfFile()
        } else {
            Toast.makeText(
                this,
                "Cannot fetch document from the file manager",
                Toast.LENGTH_SHORT
            ).show()
        }
    }
  
 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    findViewById<Button>(R.id.Import).setOnClickListener {
        // 仅触发文件选择器,不要在此处判断fileUri
        getContent.launch("application/pdf")
    }
}

2. 修复PDFTextStripper初始化错误

依次做以下配置:

  • 确保引入完整依赖,在Module级build.gradle的dependencies块中添加:
implementation 'com.tom_roush:pdfbox-android:1.8.10.0'
implementation 'com.tom_roush:fontbox-android:1.8.10.0'
  • 在proguard-rules.pro中添加混淆规则,避免PdfBox相关类和资源被混淆压缩:
-keep class com.tom_roush.** { *; }
-dontwarn com.tom_roush.**
  • 如果开启了资源压缩,在res/xml/keep.xml中添加规则保留PdfBox需要的资源:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@raw/*"
    tools:shrinkMode="strict"/>

3. 优化提取代码的空安全处理

修改extractTextPdfFile方法,提前拦截空指针场景:

private fun extractTextPdfFile() {
    var document: PDDocument? = null
    var parsedText: String = "解析失败,请检查文件是否有效"
    // 提前判断fileUri非空
    val uri = fileUri ?: return
    try {
        val inputStream: InputStream? = this.contentResolver.openInputStream(uri)
        inputStream?:return
        document = PDDocument.load(inputStream)
        val pdfStripper = PDFTextStripper()
        pdfStripper.startPage = 0
        pdfStripper.endPage = 1
        parsedText="Parsed text: " + pdfStripper.getText(document)
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        try {
            document?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
    findViewById<TextView>(R.id.file_path).text=parsedText
 }

内容的提问来源于stack exchange,提问作者Sarthak Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:36:04