Fresco引起的在arm64位机器上找不到对应的so库

背景

今天公司项目的应用,测试人员提了个bug,应用在查看pdf文档时崩溃了,看了下崩溃日志。

java.lang.UnsatisfiedLinkError: dlopen failed: "libs/armeabi-v7a/libmupdf.so" is 32-bit instead of 64-bit

libmupdf.so就是mupdf编译来的so库,意思是说该so是32位的,需要使用64位替代。确实,之前项目一直使用的是32位的,但是也有用64位的机器测过(红米note3),之前遇到的是部分手机不能加载so文件,couldn’t find *.so 这篇文章提到的问题,也解决了,能正常使用了。但,今天同一台机子,却不能使用了,想想,在这两个版本的迭代过程中,引入的库也就只有Fresco了,经过排查,问题真就出在这了。

问题

Fresco引起的在arm64位机器上找不到对应的so库_第1张图片

这是最新应用的lib下的目录结构,然后同样打旧版本包的lib目录,发现,旧的包只有armeabi-v7a这个文件夹,再查看各个文件夹下的文件,又发现,新版本的包中确实只有在armeabi-v7a文件夹下有libmupdf.so文件,其他文件夹下的都是fresco的so文件,而armeabi-v7a存放的是32位的so文件。

问题原因

64位机器默认去查找是否存在arm64-v8a目录,如果存在,就会使用(加载)该目录下合适的64位库,如果没有则回去lib下查找32位的库,而fresco的draw-pipeline太完善了考虑了64位的机器所以他的arm64-v8a下有so库,对应的系统就创建了lib 64的文件,而不再去找32位的库。但是,我们的项目中只有armeabi-v7a 32位库,以至于机器在查找到arm64-v8a目录下加载不到libmupdf.so库,然后就崩溃了。

解决方案

解决的办法当然是,让机器如何加载到我们的so文件了,那么有如下几种方案:

  1. 编译其他CPU型号对应的so文件
    如果按fresco适配的型号,那么我们要重新编译其他arm64-v8a、armeabi、x86、x86_64等4个型号的so文件,我们项目中只有mupdf这个有源码,还有其他so文件是没有源码的,再者,如果要编译的项目多,那么是多么耗时的一件事,所以,目前来看这个方案不是最佳的。

  2. 改变fresco的引用方式
    目前fresco的引用方式,是使用gradle的添加库依赖的方式
    compile ‘com.facebook.fresco:fresco:0.9.0’
    那么,如果要解决上面的问题,就要改变引用的方式:
    去掉gradle的依赖,将fresco源码clone下来自行编译,然后将armeabi-v7a目录下的so文件拷贝到项目的lib/armeabi-v7a文件夹下,接着拷贝如下几个module的aar文件
    Fresco引起的在arm64位机器上找不到对应的so库_第2张图片
    最后,就是Android Studio引入aar。关于怎么引入,可以自行查阅资料,或者有需要的话,我会在另外写一个。
    最后,你发现这种方法动的地方很多,还是很麻烦,有没有更简单的?接着看第三种方案。

  3. 修改gradle配置(究极方案)
    可以说这个方案是最完美的解决方法了,简单一本万利!
    fresco的引用还是使用gradle的compile来添加依赖,只是打开项目的build.gradle然后添加如下配置:
android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a'
        }
    }
}

ndk的abiFilters属性,填写的是需要的CPU型号,比如我只要arm32位的,所以只填写了armeabi-v7a。ok,完美解决!

参考资料:
fresco issue#504
fresco issue#458

你可能感兴趣的:(Fresco,Exception)