so库是Linux的动态链接库文件,在开发App某些功能的时候,会使用加载so库的方式运行一些特殊的代码.一般情况下,我们都会编译出基本所有平台的so库,但也有可能不兼容某些CPU而不想使用该版本so库的情况.
背景知识:
apk包在安装的时候,系统会把包中与自己的abi对应的lib目录中的so库文件拷贝到system分区中,32位机器中只有一个目录/system/lib,64位机器中有两个目录/system/lib和/system/lib64,app启动进行链接时,64位机器中会先到/system/lib64目录中去找,如果没有找到再到/system/lib目录中去找。如果你把32位的so库拷贝到了lib64目录中,会导致链接失败,同样,64位的so库被拷贝到lib目录中也会导致失败,所以so库要和目录一一对应。
如果我们的工程的so库目录中没有arm64目录,默认情况下,Android Studio会在apk中自动创建一个空的arm64-v8a文件夹,并根据一些规则把某些so库(具体是怎样的规则,我也不知道)拷贝到这个目录中,这样就导致,在64位机器上在lib64目录下找到的so库并不是正确的so库文件,从而出现了上面的错误。
引用腾讯X5内核的处理方式(它就没有提供64位的so):
64位手机无法加载x5(libmttwebview.so is 32-bit instead of 64-bit)
x5内核暂时不提供64位的so文件,在64位手机上需要让AP以32位模式运行。具体操作如下: 1.如果使用是Eclipse则需要将所有的.so文件都放置在so加载目录:lib/armeabi文件夹下(没有该目录则新建一个,
AP中没有使用到.so文件则需要拷贝任意一个32位的so文件到该目录下,如果没有合适的so可以到官网
http://x5.tencent.com/tbs/sdk.html
下载官网“SDK接入示例“,拷贝对应目录下的liblbs.so文件),
lib文件夹下不要有其他以”armeabi“开头的文件夹。
2.如果使用的是 Android studio则需要进行两项配置 (1)打开对应module中的build.gradle文件,在文件的android{}中的defaultConfig{}里(如果没有defaultConfig{}则手动添加)添加如下配置:
android {
......
defaultConfig {
......
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
}
如果配置后编译报错,那么需要在gradle.properties文件中加上
Android.useDeprecatedNdk=true
(2)找出build.gradle中配置的so加载目录:jniLibs.srcDir:customerDir,如果没有该项配置则so加载目录默认为:
src/main/jniLibs
需要将.so文件都放置在so加载目录的armeabi文件夹下(没有该目录则新建一个,AP中没有使用到.so文件则需要拷贝任意一个32位的so文件到该目录下,
如果没有合适的so可以到官网
http://x5.tencent.com/tbs/sdk.html
下载官网“SDK接入示例“,拷贝对应目录下的liblbs.so文件),
so加载目录下不要有其他以”armeabi“开头的文件夹。
可参考论坛回复:
http://bbs.mb.qq.com/thread-1473368-1-1.html
如果仍未能解决您的问题,请直接在论坛回复并描述您的问题
总结: 可以看出,上面的方法均是阻止编译Apk时打包进64位的jni库文件夹和库.所以,使用上面的方法之后,App可能也不能使用其他正常的64位so库的.好在64位CPU是兼容32位so库的,在编写代码的时候就得注意一下.