1.应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。
2.解决办法:
在build.gradle设置so文件路径,设置方法:打开app/build.gradle,在android的标签下加入如下代码
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com..a01_carmerliv"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
// 不声明ndk标签,项目默认会创建一个libapp.so的文件
ndk {
// 声明创建so库的文件名,会自动添加lib前缀, 添加了前缀,不会自动添加
moduleName "MathKit"
//声明启用Android日志, 在c/c++的源文件中使用的#include <android/log.h> 日志将得到输出
ldLibs "log"
// 声明创建指定cpu架构的so库, 不声明的话, 默认(gradle 1.5.0)会生成4中架构 多一种mips架构
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
//生成Native_Libs
task nativeLibsToJar(type: Zip, description: "create a jar archive of the native libs") {
destinationDir file("$projectDir/libs")
baseName "Native_Libs"
extension "jar"
from fileTree(dir: "libs", include: "**/*.so")
into "lib"
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(nativeLibsToJar)
}
}
dependencies {
}
注意:再在gradle.properties 文件中添加android.useDeprecatedNdk=true;重新编译
原因是Android Studio加载so类库失败,导致so文件没有编译到apk里面去,所以导致UnsatisfiedLinkError错误。
如果项目只包含了 armeabi,那么在所有Android设备都可以运行;不同CPU架构的Android手机加载时会在libs下找自己对应的目录,从对应的目录下寻找需要的.so文件;如果没有对应的目录,就会去armeabi下去寻找,如果已经有对应的目录,但是如果没有找到对应的.so文件,也不会去armeabi下去寻找了。 所以,这里需要注意工程配置哪几个so文件目录,需要加载对应的so文件,不然会报错。
如何适配各个目录,例如有一些第三方的类库只提供了armeabi下的.so文件,而工程配置不止armeabi一个目录,这就需要将armeabi下的.so文件复制到其他对应的目录下。果第三方提供了不同平台的.so文件,则复制不同平台的.so文件到项目中对应的文件夹下即可。so文件也会影响编译出的apk大小(将apk解压出来,lib目录下就为so文件目录),所以只配置armeabi一个目录,既能适配各CPU架构的手机,也能精简apk大小(微信就是只有armeabi一个目录)。
至此,本文结束!