so 文件
- 动态链接库
- 包含可被程序在运行时调用的代码和数据,在运行时动态加载和链接
- 允许程序共享资源
CPU 架构
- mips / mips64: 极少用于手机可以忽
- x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的
- armeabi: ARM v5 主要 用于 Android 4. 0 之后 的, CPU 是 32 位 的。这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈支持, 基本 已经 被 淘汰 了
- armeabi-v7a: ARM v7 目前主流版本
- arm64-v8a: 主要 用于 Android 5. 0 之后, CPU 是 64 位 的。
查找过程
对于一个cpu是arm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,分两种情况:
- 如果没有arm64-v8a文件夹,其下有armeabi-v7a(armeabi-v7a向下兼容armeabi),armeabi 。先看有没有arm64-v8a文件夹,如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常;
- 如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。
Exception:Java.lang.UnsatisfiedLinkError: dlopen failed: library “/***.so” not found
兼容性
Android 上 启动 每个 App, 都会 为 App 创建 一个 虚拟 机。 Android 的 64 位 系统,加载 32 位 的 so 或者 App 时, 会在 创建 一个 64 位 的 虚拟 机 的 同时, 还 创建 一个 32 位 的 虚拟 机, 这样, 就能 兼容 32 位 的 App 应用 了。所以, 在 App 中, 保留 一个 armeabi- v7a 版本 的 so 就 足够 了。 64 位 Android 系统 会在 32 位 的 虚拟 机上 加载 它。
- 所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件.
- 只保留这一套so文件并不保证100%不发生crash,特别是对旧设备。
- 也会失去对其他对应CPU架构的一些优化,性能有所损失。
注意点
- 没有为每个支持的CPU架构提供对应的.so文件,会发生Crash
参考
- 淘宝、微信、携程、饿了么、百度糯米只使用了armeabi
- 淘票票使用了armeabi、x86
- FaceBook、Twitter只使用了armeabi-v7a
实战
- 可以全部CPU架构都支持,安装包体积会大,性能最佳
- 可以只是用armeabi或armeabi-v7a一套,根据自己的市场用户选择
- 通过设置ndk.abiFilters显示指定支持的ABI