早期的Android系统几乎只支持ARMv5的CPU架构,目前支持七种CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。对应的ABI依次是:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64,对应Android app工程中so库的不一样目录。java
看so库的来源,是第三方提供的,仍是本身开发的。android
1.假若是集成第三方sdk,最好将它提供的都拷贝到项目中。(可是基本不多提供全面so库支持的)web
2.假若是本身开发的 ,那就根据本身的状况,编译出对应版本的so库。架构
不少设备都支持多于一种的ABI。例如ARM64和x86设备也能够同时运行armeabi-v7a和armeabi的二进制包。但最好是针对特定平台提供相应平台的二进制包,这种状况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而获得更好的性能(归功于最近的架构更新,例如硬件fpu,更多的寄存器,更好的向量化等)。app
能够经过Build.SUPPORTED_ABIS获得根据偏好排序的设备支持的ABI列表。但你不该该从你的应用程序中读取它,由于Android包管理器安装APK时,若是在对应的lib/ABI目录中存在.so文件的话,会自动选择APK包中为对应系统ABI预编译好的.so文件。函数
Android Studio工程放在jniLibs/ABI目录中(固然也能够经过在build.gradle文件中的设置jniLibs.srcDir属性本身指定)性能
Eclipse工程放在libs/ABI目录中(这也是ndk-build命令默认生成.so文件的目录)gradle
AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)优化
最终APK文件中的lib/ABI目录中ui
由于全部的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件。 mips和mips64是不支持armeabi架构的.so文件的,不过MIPS是一种高性能的嵌入式CPU构架,其出发点是高性能,主要用于路由器、猫等,基本在手机上不使用
事实上并非:这不仅影响到函数库的性能和兼容性。x86设备可以很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a, x86_64, mips64)可以运行32位的函数库,可是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)。
工程项目中,有armeabi 、armeabi-v7a两个文件夹,而两个文件夹中的库文件不同,编译运行的时候,报错java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader
在android APK的根目录有一个libs文件夹,此文件夹下包含了armeabi 、armeabi-v7a两个文件夹,有时候会有x86的;通常c代码编译成的各类.so库就会放在这两个文件夹中。
armeabi和armeabi-7a是表示cpu的类型,通常的手机或平板都是用arm的cpu,armeabi是针对普通的或旧的arm cpu,armeabi通用性强,但速度慢;armeabi-v7a是针对有浮点运算或高级扩展功能的arm cpu,速度快。
android的APP在安装时,会将APP中的so库拷贝到一个指定的目录(ApplicationInfo.nativeLibraryDir),运行时就在这个指定的目录下查找对应的so库。查找不到则会报错。
在android4.4如下版本的安装过程当中的,是先把全部so库所有寻找出来,而后优先列出cpu类型(经过ro.product.cpu.abi属性得到)目录下的so库,若是有其余的cpu类型下有跟手机cpu类型名称不一致的so库,则会将兼容cpu架构(经过ro.product.cpu.abi2属性得到)的另外的库也列出来。将列出来so库所有拷贝的系统指定目录,以供运行时加载。 即在android4.4如下版本,一个so库只要在 ro.product.cpu.abi和ro.product.cpu.abi2属性目录下至少存在一个就能够了。在android4.4如下的arm架构的设备 ro.product.cpu.abi的属性一般是armeabi-v7a, ro.product.cpu.abi2的属性值是armeabi,而且armeabi-v7a设备必定兼容armeabi。但不排除某些设备的ro.product.cpu.abi的属性为armeabi。
在android5.0及以上,因为增长了arm64的支持,app安装时的so库拷贝代码也修改了。修改为只拷贝一个最合适的目录下的so库到系统指定目录。 在arm架构下,64位cpu的优先级是arm64-v8a > armeabi-v7a > armeabi,32位cpu的优先级是armeabi-v7a > armeabi ,优先级可经过ro.product.cpu.abilist属性查看。因为android5.0是拷贝总体目录,因此在每个目录下的,都必需要有完整的so,即全部app须要so库都要有。例如64位的cpu的设备上,
若是app目录里存在arm64-v8a子目录,则只拷贝该目录下的so库,其余目录的so,即便名称不同,也不拷贝,若是arm64-v8a子目录的so库不全,则会报错。
apk中要么增长armeabi文件夹,须要注意的是,假如增长armeabi文件夹,armeabi-v7a里面的so库必定须要所有拷贝过来,不然仍是会报错。
能够删除了armeabi-v7a文件夹,保留armeabi文件夹。