原文:https://blog.csdn.net/sinat_30949835/article/details/60961092
原文:https://juejin.im/post/5c08b6405188251da07dfbe1
原文:https://blog.csdn.net/gaugamela/article/details/56281098
在原有内容上进行了整合其他的内容
ndk {
abiFilters "armeabi-v7a" // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)
}
armeabi性能较差,但是兼容性最好,v7a对于浮点计算的cpu来说性能更好
目前的手机cpu绝大多数应该是支持浮点运算的,而且安卓从2.2开始就支持v7a,所以v7a的兼容性应该也不是问题。
armeabi、armeabi-v7a、arm64-v8a、mips、mips64、x86、x86_64等abi的原理后,很久以前一般都只是用armeabi在做兼容。现在其实市面上主流的手机都支持armeabi-v7a和arm64-v8a。请看如下简介:
各版本的分析如下所示:
mips / mips64: 极少用于手机可以忽略,有兴趣的可以百度一下。
x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现 对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的
armeabi: ARM v5 这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈
armeabi-v7a: ARM v7 目前主流版本,一般市面上的骁龙系列或者麒麟系列的处理器绝大部分都是这种架构
arm64-v8a: 64位支持
所谓的ARMv8架构,就是在MIPS64架构上增加了ARMv7架构中已经拥有的的TrustZone技术、虚拟化技术及NEON advanced SIMD技术等特性,研发成的。
综上所述建议大家兼容armeabi-v7a和arm64-v8a这两个,其他架构少之又少,armeabi基本淘汰所以现在就不怎么考虑了。对于一般项目来说,足够了。
在build.gradle的android里的defaultConfig内添加如下内容:
defaultConfig {
ndk {
abiFilters "armeabi-v7a"
abiFilters "arm64-v8a"
}
如果报错
Error:(15, 1) A problem occurred evaluating project ':app'.
> Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.
请在 gradle.properties 中 添加
android.useDeprecatedNdk=true
对于新手Android开发者来说,像集成百度地图SDK、JPush等再出现找不到.so文件的问题直接只使用armeabi-v7a和arm64-v8a就足以。
为什么要设置ndk的abiFilters?
其实这个可以不设置,这样编译时,就会将项目里所有依赖资源包里的so库都打到最终的apk里。
但是有些平台,我们是不需要支持的,如果不删除的话,apk就臃肿了。如果那些so库是我们自己编译出来的,那可以直接在工程中删除对应so文件,但是如果是第三方提供的,就不好删除了,所以就需要使用abiFilters来过滤了。
如果需要针对不同的平台出不同的包,可以在productFlavors里进行设置,可参考文章:
https://link.juejin.im/?target=https%3A%2F%2Fblog.csdn.net%2Fhknock%2Farticle%2Fdetails%2F76034125
armeabi、armeabi-v7a、arm64-v8a的兼容性问题
看上上面的描述,以为新增一个so库文件可以随便根据需要适配的目录放,就错了。如果你有库文件在armeabi里有,但是armeabi-v7a目录下没有,那么运行在V7a的架构时,就会出现找不到so库文件的情况。具体描述参照:Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题。
正确的做法
- 当前市面绝大多数是arm的CPU,而且都是V7架构的了,所以可以保留armeabi或者armeabi-v7a即可。
- 如果仅保留armeabi-v7a,而有些第三方包未提供v7a的包,则可以将对应armeabi包拷贝到armeabi-v7a。
- 如果同时保留armeabi和armeabi-v7a,则需要保证两个目录下的so库文件数相同。
android {
...
splits {
abi {
enable true
reset()
include 'x86', 'armeabi-v7a', 'mips'
universalApk true
}
}
}
- enable:boolean型,表示打开或关闭APK分割功能
- reset():复位,若要使用include功能,则使用前需调用reset()
- include:创建白名单,仅构建出白名单中指定的格式
- exclude:黑名单,不会构建出黑名单中指定的格式>* compatibleScreens(仅限density):未知
- universalApk(仅限ABI):默认为true,即除了指定的格式外,还会构建出一个通用的APK
android { ... splits { density { enable true exclude "ldpi", "tvdpi", "xxxhdpi" compatibleScreens 'small', 'normal', 'large', 'xlarge' } }