与 so 有关的一个长年大坑

AlphaPose复现配置教程 AlphaPose是一种准确的多人姿态估计器,这是第一个在COCO数据集上达到70+ mAP (75 mAP)和在MPII数据集上达到80+ mAP (82.1 mAP)的开源系统。为了匹配跨帧的同一人的姿态,我们还提供了一种高效的在线姿态跟踪器,称为Pose Flow。这是第一个在PoseTrack挑战数据集上达到60+ mAP (66.5 mAP)和50+ MOTA (58.3 MOTA)的开源在线姿态跟踪器。AlphaPose支持Linux和Windows操作系统!指路👉。 阅读详情

Android 应用开发中不可避免的会引入第三方的代码。如果是开源项目风险相对可控,如果引入商用的 SDK 那就要谨慎了,难免会有这样或那样的问题。比如我们今天要说的这一个。

260b1911b1520cdd7059fc988bfa9ac1_b

对集成过第三方 SDK 的同学,上图中的目录结构应该不陌生。正常情况下我们只需要将不同版本的 so 文件分别放置。但如果我们要集成的这个第三方 SDK 偏偏没有 arm-v7a 的版本呢?是删除 armeabi-v7a 目录只保留 armeabi ?还是说两个目录下 .so 文件数不同也没有关系?系统会加载哪个 .so 呢?

如果只对结论感兴趣可以直接跳到最后

为了方便说明我们先引入 FAT Binary 的概念。我们知道不同的 CPU 支持的指令集也不一样,那么如果我们需要让 App 尽可能不同的 CPU 上都可以正常运行该怎么做呢?简单,只需要将不同版本的 Binary 放在一个文件里,运行时按需取用就可以了。这就是 FAT Binary 的典型实现。Android 实现 FAT 的方式有些不同,就是上边提到的将 .so 文件放置在相应文件夹中。在 Android 系统中 ndk 默认会生成如下 7 种 so。

51a526079ad6c0d4410425433f3f27b0_b

在 apk 文件中带这么多版本的 .so 是一种很不经济的做法:

  • mips / mips64: 极少用于手机可以忽略
  • x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现 对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的
  • armeabi: ARM v5 这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈
  • armeabi-v7a: ARM v7 目前主流版本
  • arm64-v8a: 64位支持

这样我们就可以明确 mips, mips64, x86, x86_64 这 4 个 .so 我们是不需要的。

我们回到开头提到的问题:

假定我们现在的情况是这样的(b.so 就是那个只有 armeabi 版本的第三方 so):

d461cdc25dec4bc2c7ea7a7080173bf6_b

如果这样放置的话,在 ARM / ARM v7 两种设备上运行 apk 时会分别执行哪个 so 呢?

答案是:不确定……

这么坑爹的答案是怎么来的呢?

由于 Android 上 FAT binrary 的设计如此阳春,在 apk 安装时就需要根据 CPU 情况执行对应版本 so 的拷贝。对上边的情况最合理的一种做法应该是使用 armeabi-v7a/a.so 和 armeabi/b.so 这两个文件。Google 最初也是这么想的,然后就引入了 Bug…

Native library copy issue when install apk with different abi native libraries on device

b93562bbfa02d371ccdd4bda4eaefce0_b

上图是到 Android 4.4 还在使用的 so 文件拷贝逻辑,看起来没有问题?

坑爹是 Android 在安装 apk 文件时没有保证 zip entry 的扫描顺序,所以同样的文件放置会带来两种不同的安装结果:

793431faf310fa7c9fc05f5ccc410afe_bcc920ddc61541f58e5adb0d09685eda7_b

看的有点头晕?简而言之,如果按我们上面的放置方式,安装后系统可能只拷贝了 armeabi-v7a/a.so。如果执行到 b.so 的逻辑,程序显然会 crash。

这边还有个小插曲,这个 bug 的发现者在提交时其实已经给出了完善的解决方案,但在经历了快有小一年的 code review 后 Android 官方表示:我们自己另起炉灶修好了=_=。

8e44486bbfb9a853170c404db074622e_b

这个问题确实在 Android 5.0 已经 “修复” 了。“修复” 方式简单粗暴,不再以文件为粒度匹配 abi,直接拷贝整个文件夹=_=。所以如果按我们之前的放置方法,在 Android 5.0+ 如果执行到 b.so 也是一定会 crash 的。

上面提到,只保留 armeabi 文件夹从性能角度是不明智的。正确的做法是将 armeabi/b.so 复制一份到 armeabi-v7a/b.so. 这是由于 ARM v7 是前向兼容 ARM v5 的。

撇开上面曲折离奇的故事,放置 so 文件的正确姿势其实就两句话:

  • 为了减小 apk 体积,只保留 armeabi 和 armeabi-v7a 两个文件夹,并保证这两个文件夹中 so 数量一致
  • 对只提供 armeabi 版本的第三方 so,原样复制一份到 armeabi-v7a 文件夹

作者:Caspar

链接:https://zhuanlan.zhihu.com/p/21359984

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载请注明:Android开发中文站 » 与 so 有关的一个长年大坑

从菜鸟到高手:我的Abaqus壳单元S4R、S3R、S8R选择心路历程 第一次打开Abaqus的单元库时,我被琳琅满目的壳单元类型晃花了眼。S4R、S3R、S8R、STRI65、S9R5...这些看似随意的字母数字组合,背后却隐藏着影响仿真精度的关键密码。作为一名从土木工程转行到汽车结构仿真的工程师,我花了三年时间才真正理解如何根据问题特性精准选择壳单元。这段学习历程充满试错与顿悟,今天就用几个关键案例,分享我的壳单元选择方法论。 阅读详情

相关推荐

实现自动打包py及替换pyinstaller --add-data参数的方法

实现自动打包py及替换pyinstaller --add-data参数的方法

isS_MK_GmbH的博客 3468

Android 将多个静态库合并为一个静态库或动态库

有时我们使用第三方提供的静态库加上我们自己的代码需要重新编译出库文件或可执行文件,如果生成可执行文件直接参考https://blog.youkuaiyun.com/u013463707/article/details/90754571 即可。 但是如果还想生成库文件,直接修改Android.mk的include $(BUILD_EXECUTABLE) 为include $(BUILD_STATIC_LIB...

u013463707的专栏 4111

航空大数据——项目资源汇总及开源(四)

ADS-B项目开源大礼包

cyc头发还挺多的博客 4988

Android NDK系列(六)- 文件拆分与合并

NDK系列(一)-AS使用javah生成so文件 NDK系列(二)-AS使用CmakeLists生成so文件 NDK系列(三)-AS编写C文件没有提示和不识别NULL NDK系列(四)-AS生成jar包、导入so库并使用方法 NDK系列(五)- AS导入so三方库,使用C/C+方法文件的拆分和合并是一个常见的功能,使用java是可以完成的。 Android合并文件的三种方式

SingleShu的博客 1207

【AI智能体】Codex 插件从使用到项目开发实战操作详解

Codex 插件从使用到项目开发实战操作详解

congge 7648

DICOM图像知识:深入详解DICOM的层级关系

解析DICOM的四个主要层级:Patient(患者)、Study(检查)、Series(序列)和SOP(服务-对象对),探讨它们之间的关系、各自的唯一标识符以及在实际应用中的用途

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 3305

Android Studio Module 中的So 文件和 App So文件合并问题

其实在开发中我们经常会遇到一些c++语言或者其他第三方的so文件,有时候我们,胡乱的方在app下面的libs对应的指令集文件夹下,缺发现根本就用不了,这个时候我们就找不到原因,明明我声明的,为何报错说找不到方法,这里我要简单说明下。 其实一个项目只能有一个jniLibs文件夹就决定了,我们的so文件必须放在一个地方,所以在app和module都含有so文件的时候,需要把app里面的so文件放到mo

幸福就冒个泡的专栏 6357

基于 ESP32 与 TDS 传感器的水培营养液离子浓度自动配比系统设计与实现

本系统以 ESP32 为主控芯片,结合 TDS(总溶解固体)传感器实时监测水培营养液中的离子浓度,通过蠕动泵自动补充浓缩营养液或清水,实现营养液 EC 值的闭环自动配比。系统适用于家庭及小型农场的水培种植场景,可稳定维持营养液浓度在作物生长所需的最佳区间。

weixin_42300449的博客 82

android打包so文件到apk

使用android SDK原代码 开发APK,将so文件打包进apk,这样可以只提供给客户一个apk. 1.含义全代码的so打包. a)建立工程,并使用本地调用,java文件如下 view source print? 01.package test.jni; 02.import android.app.Activity; 03.import android.os.Bundle; 0...

sharp2wing的专栏 223

阿里云百炼全解析:一站式大模型开发平台的架构与行业实践

摘要: 阿里云百炼平台通过一站式架构革新大模型开发范式,将传统碎片化工具链整合为统一工作流,实现开发周期从月级到小时级的跃迁。其核心架构包含接入层、引擎层与资源层,关键技术突破包括MCP服务协议、多模态引擎及高性能训练优化。平台提供全生命周期开发支持,从数据准备到模型部署,并通过VPC隔离、数据加密构建企业级安全体系。已在医疗、电力等行业实现显著增效,如阿斯利康药物分析系统准确率提升至95%。未来将向多Agent协同、边缘计算等方向演进,推动AI技术深度融入产业核心。

fudaihb的博客 1991

多层环境室内定位系统综述总结

本文是一篇发表于2025年《IEEE Access》期刊的综述论文,由埃及开罗美国大学与卡塔尔卡内基梅隆大学团队合作完成,聚焦多层环境室内定位系统的核心挑战、技术方案及未来方向,填补了该领域缺乏全面综述的空白。

程序员石磊 445

Linux下动态链接库的生成与使用

Linux 下动态链接库的生成与使用 动态链接库介绍 动态链接库是一种不可以直接执行的二进制程序文件,它允许程序共享执行一段公用的代码和资源。 在 Linux 平台上动态链接库是以 .so 作为后缀名的。 相对于静态链接库来说,动态链接库在编译的时候并没有被编译进目标代码中,直到程序在执行到动态链接库中的相关函数的时候,才会调用动态链接库中的函数运行,因此使用动态链接库所生成的可执行文件比较小。正...

飘雪冰峰的博客 931

11、基于STM32的智能药盒

当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未有的速度被单片机智能控制系统所取代。嵌入式具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。

行走的皮卡丘 6104

与 .so 有关的一个长年大坑

Android 应用开发中不可避免的会引入第三方的代码。如果是开源项目风险相对可控,如果引入商用的 SDK 那就要谨慎了,难免会有这样或那样的问题。比如我们今天要说的这一个。 对集成过第三方 SDK 的同学,上图中的目录结构应该不陌生。正常情况下我们只需要将不同版本的 .so 文件分别放置。但如果我们要集成的这个第三方 SDK 偏偏没有 arm-v7a 的版本呢?是删除 armeabi-v7...

Liuqz2009的专栏 254

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

android .so文件详解以及兼容性

Android 设备的CPU类型通常称为ABIs 问题描述 解决方法 1解决之前的截图 2解决后的截图 3解决方法 4建议 为什么你需要重点关注so文件 App中可能出错的地方 其他地方也可能出错 使用android-21平台版本编译的so文件运行在android-15的设备上 混合使用不同C运行时编译的so文件 没有为每个支持的CPU架构提供对应的so文件 将so文件放

代码猫 2196

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题

转自:【欧阳鹏】http://blog.youkuaiyun.com/ouyang_peng Android 设备的CPU类型(通常称为”ABIs”) armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它. arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一。 armeabi: 第5代、第6...

爬行的菜鸟的博客 2210

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题

转自 https://www.baidu.com/link?url=3RvOfagX2Dm7jXTs5-hVKHBTY59pCX1TJT5gGpOJISC-l85Kz2iyQIJffjsyfdKl_iB6DAB5uF_Mr2GLYzIA86ha5OUpFZnMd14dWzAtYzu&wd=&eqid=8b76c4bf0001bc48000000065c44928e Androi...

hnlgzb的专栏 1418

关于Android so库的那些事

Android 设备的CPU类型通常称为ABIs问题描述解决方法 1解决之前的截图2解决后的截图3解决方法4建议为什么你需要重点关注so文件App中可能出错的地方其他地方也可能出错 使用android-21平台版本编译的so文件运行在android-15的设备上混合使用不同C运行时编译的so文件没有为每个支持的CPU架构提供对应的so文件将so文件放在错误的地方只提供armeabi

weijinqian0的博客 996

关于Android中.so库的坑和适配Https的注意事项

关于Android .so文件概述早期的Android只支持ARMv5的CPU,现在支持ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI.关于ABI支持很多设备都支持多于一种的ABI,ARM64和x86设备也可以同时运行armeabi-v7a和armeabi

BoBoMEe 2869
上一篇: Android 进程保活
下一篇: 关于Android的.so文件你所需要知道的
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值