现象描述
Android Studio打出来的包在64位机器上报以下
java.lang.UnsatisfiedLinkError: dlopen failed: “libfoobar.so”
我们是在工程目录中将32位的so库拷贝到arm64-v8a中的
原因分析
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库文件,从而出现了上面的错误
解决办法
解决办法就是阻止Android Studio自动的生成arm64-v8a目录,我们自己写脚本把对应的so库文件拷贝到build对应的目录下
在build.gradle中写入如下的脚本
sourceSets.main {
jni.srcDirs = []
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkLibsToJar
}
task ndkLibsToJar(type: Zip, description: 'Create a JAR of the native libs') {
destinationDir new File(buildDir, 'libs')
baseName 'ndk-libs'
extension 'jar'
from(new File(buildDir, 'libs')) { include '**/*.so' }
into 'lib/'
}
同时,我们把工程目录中的对应的arm64-v8a目录删掉,大功告成