最近项目要求加载、展示PDF文件,因为之前项目中已经有X5浏览器了,用X5内核加载PDF文件也简单,就很快写完。但是没想到,测试出来几个坑。这里总结整理下。
读写权限,必须要有
写在前面:引入PDFView,会让包的体积大几M;用其他的,我查了下,有各种问题:如水印加载不全、放大缩小不顺、超过3M的PDF文件就会OOM等。最后选择了PDFView
PDFView 的GitHub 地址
https://github.com/barteksc/AndroidPdfViewer
X5内核(TbsReaderView)+PDFView 实现PDF的加载,已经成功,并应用到项目中了
我的测试用PDF文件,找了3个:几百K、几兆、18M
全部源代码我会放在后面(关于项目包名的,我都去掉了,复制的时候,用自己需要的代码就好),我这里先说我踩的坑或因项目需求而产生的额外操作
项目要求:
1、在线加载,本地不保留PDF文件;
2、不做缓存。如:一个PDF文件有100页,当前打开看到50页,退出去,再次进来,加载完后,从第一页开始;
3、加载PDF文件正常(这点我单独写出来,是因为X5内核启动有问题,和这个“要求”冲突,后面会说)
实现项目要求办法:
1、TbsReaderView加载PDF,是把PDF先下载了,然后加载,但是项目要求本地不保留文件,我想到个折中方法:先下载展示,等退出界面的时候,删掉文件。
这里会有个问题:用户不退出呢?如果用户加载完界面,不杀死APP,直接切换到手机文件夹,就能找到PDF文件了。会有这个问题
2、我看了不少技术博客,没有提及清除PDF文件的,但是我在实现功能的过程中,看到了这个
//存放临时文件的目录。运行后,会在
//Environment.getExternalStorageDirectory().getPath() 的目录下生成.tbs 的文件
bundle.putString(
"tempPath",
Environment.getExternalStorageDirectory().getPath()
)
然后我就找啊找,在文件夹的根目录下(因为后面没有加自定义文件夹的名字),找到了这个文件夹
.TbsReaderTemp包名
如:项目的包名是 com.chen.demo
这个文件夹的名字就是
.TbsReaderTempcom.chen.demo
在 .TbsReaderTemp包名 中,真有 .tbs 文件。进过测试(1、打开PDF文件,定位到某一页;2、退出界面;3、重新打开PDF文件,查看文件定位到的页数;4、重复1、2;5、切换到这个文件夹下;6、删除 .tbs 文件;7、回到APP,重新打开PDF文件,查看文件定位到的页数;8、和步骤3中的情况做对比),删除 .tbs 后,真的可以从第一页开始展示
注意:
(1)删掉这个临时文件,重新打开PDF文件时,会慢一点。这个需要自己恒量了。
(2).TbsReaderTemp包名 这个文件夹,在一些手机上,是不可见的。如:我的 华为mate20(安卓10、EMUI 10.1.0 )手机,就找不到,但是通过文件是否存在,可以判断出来
val s: String =
"${Environment.getExternalStorageDirectory().getPath()}/.TbsReaderTemp包名/"
Log.e("s:",s)
val f: File = File(s)
if (f.exists()) {
......
}
3、为了解决PDF的正确加载,我遇到了一个巨坑:X5内核,首次安装启动的时候,不一定会加载成功,如果加载失败 result 会变成false,即:tbsReaderView 无法加载PDF
val result = tbsReaderView!!.preOpen("pdf", false)
if (result) {
//X5内核正常,可以直接展示PDF文件
tbsReaderView!!.openFile(bundle)
}
我查了资料,也通过自己大量的卸载安装,得出下面的结论:
(1)手机上有腾讯类的产品(如:QQ、微信),可能会在手机上安装X5内核,如果有了内核,其他APP会共用;
(2)APP启动时,会调用
fun initX5Core() {
QbSdk.setDownloadWithoutWifi(true)
QbSdk.initX5Environment(this, object : QbSdk.PreInitCallback {
override fun onCoreInitFinished() {
Log.d("X5core", "x5加载结束")
}
override fun onViewInitFinished(p0: Boolean) {
Log.d("X5core", "x5加载结束$p0")
}
})
}
如果是第一次安装启动,有可能 onViewInitFinished 的 p0 值是false,表示X5初始化、加载失败,会导致后面的 tbsReaderView 无法加载PDF文件;安装完APP后,从第二次启动APP开始,每次都是正常的
(3)和网络情况也有关系。如果第一次安装、启动,是在WIFI情况下,onViewInitFinished 小概率会 p0 = false,如果是流量情况下 大概率 p0 = false
(4)在 result = false 时,重新调用 initX5Core() 也无法解决第一次安装、启动时 X5 初始化失败的问题
解决办法就是:再引入一个其他的PDF加载控件(如:PDFView),如果X5不行了,就切换用其他的去加载。
为什么不直接用PDFView呢?
经过对比:PDFView在展示页数、界面分页等方面,没有 tbsReaderView 好(PDFView的功能方法其实很多,我还没研究透彻,也可能是我研究不透彻的原因)。tbsReaderView更符合我的要求、使用习惯。
以下是源代码
我这里假设X5相关已经集成成功了(so文件项目已经具备了)
1、
api 'com.tencent.tbs.tbssdk:sdk:43903'
2、Application 的 onCreate中
fun initX5Core() {
QbSdk.setDownloadWithoutWifi(true)
QbSdk.initX5Environment(this, object : QbSdk.Pr

本文介绍了在安卓项目中利用腾讯X5内核(TbsReaderView)和PDFView加载PDF文件的实现过程及遇到的问题。在不保留PDF本地文件、不做缓存的情况下,通过下载并立即删除文件来满足需求。文章详细阐述了删除.TbsReaderTemp文件夹中.tbs文件以避免页面定位问题,以及首次安装启动时X5内核可能加载失败的解决方案。同时,对比了PDFView和tbsReaderView的优缺点,并提供了相关源代码。
+PDFView)&spm=1001.2101.3001.5002&articleId=109215501&d=1&t=3&u=c8e09ef49e814f5c8975346e215e5dfd)
8529

被折叠的 条评论
为什么被折叠?



