当前位置: 首页 > news >正文

Android中的ABI

Android中的ABI

  • ABI是Application Binary Interface的缩写。

  • ABI常表示两个程序模块之间的接口,且其中一个模块常为机器码级别的library或操作系统。

  • ABI定义了函数库的调用、应用的二进制文件(尤其是.so)如何运行在相应的系统平台上等细节。

  • Android目前支持以下七种ABI:armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips、mips64

Android中的CPU

  • 不同的Android设备使用支持不同指令集的CPU。

  • Android目前有以下七种cpu架构:ARMv5、ARMv7、ARMv8、x86、x86_64、MIPS和MIPS64

Android中的ABI与CPU

  • 每种CPU架构都有其自己支持的ABIs。可通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。
CPU(纵向)/ABI(横向)armeabiarmeabi-v7aarm64-v8ax86x86_64mipsmips64
ARMv5支持(1)
ARMv7支持(2)支持(1)
ARMv8支持(3)支持(2)支持(1)
x86支持(3)支持(2)支持(1)
x86_64支持(4)支持(3)支持(2)支持(1)
MIPS支持(1)
MIPS64支持(2)支持(1)

表中的数字表示最终选择安装的ABI的优先级,1为最高。

  • 每种CPU架构都有自己对应的最优ABI。
CPU架构最优ABI
ARMv5armeabi
ARMv7armeabi-v7a
ARMv8arm64-v8a
x86x86
x86_64x86_64
MIPSmips
MIPS64mips64
  • 应用安装到设备时,只有该设备的CPU架构支持的最优so库才会被安装。

    如:x86架构的设备支持x86、armeabi-v7a和armeabi等ABI。但优先级从高到低依次为x86、armeabi-v7a、armeabi。系统会根据此顺序寻找首个可用的最优的so库,找到则结束。

  • x86设备包含ARM模拟层,能够很好地运行ARM类型的so库,但并不保证100%不发生Crash。

  • 64位设备(arm64-v8a, x86_64, mips64)能够运行32位的so库。但是以32位模式运行时,会丢失专为64位优化过的性能特征(ART, WebView, Media, etc.)。

NDK兼容性

  • NDK平台不是向后兼容(兼容过去的版本)的,而是向前兼容(兼容未来的版本)的。

  • NDK编译的版本应该尽量使用较低的版本,如minSdkVersion="8"。

Android中的so库

so库的名称和文件名

  • so库的名称可任意,如daking。

  • so库的文件名必须以lib开头。如libdaking.so,其中lib是必要前缀,daking才是这个库的名称。

so库文件的路径

  • 在Android Studio中的路径:

    默认要放在模块/src/<SourceSet>/jniLibs/<ABI>/下。如:将so库放在app/src/main/jniLibs/armeabi

    可在模块的build.gradle中修改配置指定so库的路径。如,将so库放在app/libs/armeabi下,并修改配置如下:

 android {...sourceSets {main {jniLibs.srcDirs = ['libs']}}
}
  • 在Eclipse中的路径:

    放在libs/<ABI>下。

  • 在Android系统中的路径:

    /data/data/<应用包名>/lib/下。

  • 在aar包中的路径:

    jni/<ABI>下。

so库的代码加载

  • System.loadLibrary("so库的名称");如System.loadLibrary("daking");会加载该应用下的libdaking.so文件。

  • System.load("so库文件的全路径");如System.load("/data/data/com.daking.app.demo/libdaking.so");会加载包名为com.daking.app.demo的应用的libdaking.so文件。

so库的使用建议

  • 理论上应该为每个ABI目录提供对应的so库。但是Android支持7种ABI,若全部支持,必然导致APK包过大。

  • 一般只保留armeabi、armeabi-v7a这两个ABI的so库。

    mips/mips64:极少用于手机,可忽略。

    x86/x86_64:x86架构的手机的市场占有率很低,约为1%左右。而且x86架构都包含ARM模拟层,兼容ARM类型的ABI。注意,模拟器为x86架构。

    arm64-v8a:64位ARM架构。可用32位模式运行armeabi-v7a和armeabi。

    armeabi-v7a:截止于2017年2月,目前主流版本AMRv7。

    armeabi:老版本ARMv5,但仍需要兼容。

  • 通过上面的分析,不难发现,只要提供armeabi便可兼容新/旧设备。但armeabi缺少对浮点数机器的支持,存在性能瓶颈。应该将armeabi目录中的so库拷贝一份到armeabi-v7a目录中。

  • 总结:

    为了减小apk体积,只保留armeabi和armeabi-v7a两个目录,并保证这两个目录中so库数量一致。

    对只提供armeabi版本的第三方so库,原样复制一份到armeabi-v7a目录中。

so库的常见错误

  • 使用高版本编译出的so库运行在低版本的平台上会出错。考虑到NDK是向前兼容的,应使用低版本编译。

  • so库放置的路径有误。

  • 没有在每个生效的ABI目录下放置对应的so库。

    1. 若某应用有armeabi和arm64-v8a两个ABI目录,armeabi目录里有a.sob.so,但arm64-v8a只有a.so
    2. 当ARMv8设备在安装此应用时,根据ABI优先级,首先发现arm64-v8a目录存在,并决定使用此ABI下的so库。
    3. 但arm64-v8a目录中没有b.so,于是报错。
    4. 此时的解决方案有:一,删除arm64-v8a目录;二,arm64-v8a目录的so库情况要与armeabi一致。

工具

  • Native Libs Monitor,监控设备上所有已安装的App,列出它们apk中包含的so库以及检测出最终安装到的so库。

http://www.lryc.cn/news/113667.html

相关文章:

  • Python爬虫在用户行为模型构建中的应用与挑战
  • LangChain与大模型的学习
  • C语言标准定义的32个关键字
  • PE半透明屏是怎么制造的?工艺、材料、应用
  • linux文本三剑客---grep,sed,awk
  • leaflet-uniapp 缩放地图的同时 显示当前缩放层级
  • [Securinets CTF Quals 2023] Admin Service,ret2libc,One is enough
  • 计算机组成原理-笔记-第二章
  • mysql大量数据导入记要
  • 极狐GitLab 全新「价值流仪表盘」使用指南
  • 通过logrotate实现nginx容器内日志按天存储
  • 广东珠海电子行业导入MES系统需要注意什么
  • 小红书2023/08/06Java后端笔试 AK
  • 3、有序数组的平方
  • 用于自然语言处理 (NLP) 的 MLOps
  • C#抽象静态方法
  • 小研究 - Mysql快速全同步复制技术的设计和应用(一)
  • HTML <samp> 标签
  • C之(8)linux动态库编译框架
  • Zabbix网络拓扑配置
  • 2.4G芯片XL2408开发板,SOP16封装,芯片集成1T 8051内核单片机
  • iPhone苹果手机地震预警功能怎么开启?
  • Storm学习之使用官方Docker镜像快速搭建Storm运行环境
  • 【GTest学习】
  • [JAVAee]网络通信基础
  • 【HDFS】BlockManager#checkRedundancy方法详解
  • c++ 拷贝构造
  • MISRA 2012学习笔记(1)-Directives
  • 升级node版本后vue2的项目node-sass、sass-loader安装报错(14.x升级到16.x)
  • 深入理解CSS选择器:选择正确的方式掌控样式与布局