• Android 设备的CPU类型通常称为ABIs
  • 问题描写叙述
  • 解决方法
    • 1解决之前的截图
    • 2解决后的截图
    • 3解决方法
    • 4建议
    • 为什么你须要重点关注so文件
    • App中可能出错的地方
    • 其它地方也可能出错
      • 使用android-21平台版本号编译的so文件执行在android-15的设备上
      • 混合使用不同C执行时编译的so文件
      • 没有为每一个支持的CPU架构提供相应的so文件
      • 将so文件放在错误的地方
      • 仅仅提供armeabi架构的so文件而忽略其它ABIs的
  • 很多其它參考

Android 设备的CPU类型(通常称为”ABIs”)

  1. armeabiv-v7a: 第7代及以上的 ARM 处理器。

    2011年15月以后的生产的大部分Android设备都使用它.

  2. arm64-v8a: 第8代、64位ARM处理器,非常少设备,三星 Galaxy S6是当中之中的一个。
  3. armeabi: 第5代、第6代的ARM处理器,早期的手机用的比較多。
  4. x86: 平板、模拟器用得比較多。
  5. x86_64: 64位的平板。

问题描写叙述

今天測试人员測试集成版本号时除了一个bug:关于华为 Mate 8手机Android 6.0系统执行刚刚提測的版本号时,出现闪退的bug。而小米 4 手机Android 6.0系统却没有出现不论什么bug,执行良好。后来查看本人相关模块的代码,发现本人集成版本号相关模块的代码和分支版本号相关模块的代码是一模一样的。那就是说本人把分支代码合并到主干代码是没有问题的,所以去查看主干代码的问题。

经过一番查看提交日志。发现有位同事再我合并代码之前,提交了一个关于友盟推送的so文件的记录,原来他加入了一个arm64-v8a文件夹,里面有友盟推送的arm64-v8a的so库文件。而其它的so库文本却没有arm64-v8a相应的版本号。

通过百度查到知乎有一段关于arm64-v8a的解释:

arm64-v8a是能够向下兼容的,但前提是你的项目里面没有arm64-v8a的文件夹,假设你有两个文件夹armeabi和arm64-v8a,两个文件夹,armeabi里面有a.so 和 b.so,arm64-v8a里面仅仅有a.so,那么arm64-v8a的手机在用到b的时候发现有arm64-v8a的文件夹,发现里面没有b.so。就报错了。所以这个时候删掉arm64-v8a文件夹,这个时候手机发现没有适配arm64-v8a,就会直接去找armeabi的so库,所以要么你别加arm64-v8a,要么armeabi里面有的so库,arm64-v8a里面也必须有

作者:green jim
链接:http://www.zhihu.com/question/36893314/answer/78467097
来源:知乎
著作权归作者全部。商业转载请联系作者获得授权。非商业转载请注明出处。

发现原来华为 Mate 8手机是64位的操作系统。而小米 4 手机是32位的操作系统,所以小米 4 手机手机执行APP没bug,而华为 Mate 8手机执行APP出现闪退bug。

解决方法

1、解决之前的截图:


从截图能够看出来,第一个项目中有 arm64-v8a。而没有x86文件夹。第二个项目中没有 arm64-v8a,而有x86文件夹。第一个项目是作为项目引用导入到第二个项目中的。

2、解决后的截图:


从截图能够看出来,第一个项目中和第二个项目中没有的libs文件夹下,都是armeabi-v7a、armeabi、x86三个文件夹,保持一致。

第一个项目是作为项目引用导入到第二个项目中的。

3、解决方法:

解决方法是:从友盟官方中去下载x86的相关so文件,放在x86文件夹下,把arm64-v8a文件夹删除。将全部关于so文件的都要保持一致,即:假设你要加入一个armeabi-v8a文件夹,以下放第三方的armeabi-v8a相关的so文件,那么你其它的so文件都要有相应想armeabi-v8a版本号,不然就会报错。

4、建议

来自于博客:《与 .so 有关的一个长年大坑 》给的建议是:

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


以下文章转载于asce1885(简书作者):关于Android的.so文件你所须要知道的
(原文链接:http://www.jianshu.com/p/cb05698a1968)
著作权归作者全部,转载请联系作者获得授权。并标注“简书作者”。

早期的Android系统差点儿仅仅支持ARMv5的CPU架构,你知道如今它支持多少种吗?7种!

Android系统眼下支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起)。MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。

应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)怎样执行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android系统上,每一个CPU架构相应一个ABI:armeabi,armeabi-v7a。x86。mips,arm64-v8a,mips64,x86_64。

为什么你须要重点关注.so文件

假设项目中使用到了NDK。它将会生成.so文件,因此显然你已经在关注它了。假设仅仅是使用Java语言进行编码,你可能在想不须要关注.so文件了吧。由于Java是跨平台的。

但其实,即使你在项目中仅仅是使用Java语言。非常多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经嵌入了.so文件,并依赖于不同的ABI。

比如,项目中使用RenderScript支持库。OpenCV,Unity,android-gif-drawable。SQLCipher等。你都已经在生成的APK文件里包括.so文件了,而你须要关注.so文件。

Android应用支持的ABI取决于APK中位于lib/ABI文件夹中的.so文件,当中ABI可能是上面说过的七种ABI中的一种。

Native Libs Monitor这个应用能够帮助我们理解手机上安装的APK用到了哪些.so文件。以及.so文件来源于哪些函数库或者框架。

当然。我们也能够自己对app反编译来获取这些信息,只是相对麻烦一些。

非常多设备都支持多于一种的ABI。

比如ARM64和x86设备也能够同一时候执行armeabi-v7a和armeabi的二进制包。但最好是针对特定平台提供相应平台的二进制包,这样的情况下执行时就少了一个模拟层(比如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于近期的架构更新,比如硬件fpu,很多其它的寄存器。更好的向量化等)。

我们能够通过Build.SUPPORTED_ABIS得到依据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,由于Android包管理器安装APK时。会自己主动选择APK包中为相应系统ABI预编译好的.so文件。假设在相应的lib/ABI文件夹中存在.so文件的话。

App中可能出错的地方

处理.so文件时有一条简单却并不知名的重要法则。

你应该尽可能的提供专为每一个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每一个ABI文件夹提供相应的.so文件。

当一个应用安装在设备上,仅仅有该设备支持的CPU架构相应的.so文件会被安装。在x86设备上,libs/x86文件夹中假设存在.so文件的话,会被安装,假设不存在。则会选择armeabi-v7a中的.so文件,假设也不存在,则选择armeabi文件夹中的.so文件(由于x86设备也支持armeabi-v7a和armeabi)。

其它地方也可能出错

当你引入一个.so文件时,不止影响到CPU架构。

我从其它开发人员那里能够看到一系列常见的错误,当中最多的是”UnsatisfiedLinkError”,”dlopen: failed”以及其它类型的crash或者低下的性能:

使用android-21平台版本号编译的.so文件执行在android-15的设备上

使用NDK时。你可能会倾向于使用最新的编译平台,但其实这是错误的,由于NDK平台不是后向兼容的。而是前向兼容的。

推荐使用app的minSdkVersion相应的编译平台。

这也意味着当你引入一个预编译好的.so文件时,你须要检查它被编译所用的平台版本号。

混合使用不同C++执行时编译的.so文件

.so文件能够依赖于不同的C++执行时。静态编译或者动态载入。混合使用不同版本号的C++执行时可能导致非常多奇怪的crash,是应该避免的。作为一个经验法则,当仅仅有一个.so文件时,静态编译C++执行时是没问题的。否则当存在多个.so文件时,应该让全部的.so文件都动态链接同样的C++执行时。

这意味着当引入一个新的预编译.so文件,并且项目中还存在其它的.so文件时。我们须要首先确认新引入的.so文件使用的C++执行时是否和已经存在的.so文件一致。

没有为每一个支持的CPU架构提供相应的.so文件

这一点在前文已经说到了,但你应该真的特别注意它,由于它可能发生在根本没有意识到的情况下。

比如:你的app支持armeabi-v7a和x86架构,然后使用Android Studio新增了一个函数库依赖,这个函数库包括.so文件并支持很多其它的CPU架构,比如新增android-gif-drawable函数库:

compile ‘pl.droidsonroids.gif:android-gif-drawable:1.1.+’

公布我们的app后,会发现它在某些设备上会发生Crash。比如Galaxy S6,终于能够发现仅仅有64位文件夹下的.so文件被安装进手机。

解决方式:又一次编译我们的.so文件使其支持缺失的ABIs,或者设置

ndk.abiFilters

显示指定支持的ABIs。

最后一点:假设你是一个SDK提供者,但提供的函数库不支持全部的ABIs,那你将会搞砸你的用户,由于他们能支持的ABIs必将仅仅能少于你提供的。

将.so文件放在错误的地方

我们往往非常easy对.so文件应该放在或者生成到哪里感到困惑,以下是一个总结:

  • Android Studio工程放在jniLibs/ABI文件夹中(当然也能够通过在build.gradle文件里的设置jniLibs.srcDir属性自己指定)
  • Eclipse工程放在libs/ABI文件夹中(这也是ndk-build命令默认生成.so文件的文件夹)
  • AAR压缩包中位于jni/ABI文件夹中(.so文件会自己主动包括到引用AAR压缩包的APK中)
  • 终于APK文件里的lib/ABI文件夹中
  • 通过PackageManager安装后,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath文件夹中;在大于等于Android 5.0的系统中。.so文件位于app的nativeLibraryRootDir/CPU_ARCH文件夹中。

仅仅提供armeabi架构的.so文件而忽略其它ABIs的

全部的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件。因此似乎移除其它ABIs的.so文件是一个降低APK大小的好技巧。但其实并非:这不仅仅影响到函数库的性能和兼容性。

x86设备能够非常好的执行ARM类型函数库。但并不保证100%不发生crash。特别是对旧设备。64位设备(arm64-v8a, x86_64, mips64)能够执行32位的函数库。可是以32位模式执行,在64位平台上执行32位版本号的ART和Android组件。将丢失专为64位优化过的性能(ART,webview,media等等)。

以降低APK包大小为由是一个错误的借口,由于你也能够选择在应用市场上传指定ABI版本号的APK。生成不同ABI版本号的APK能够在build.gradle中例如以下配置:

android {... splits {abi {enable truereset()include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs foruniversalApk true //generate an additional APK that contains all the ABIs}}// map for the version codeproject.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]android.applicationVariants.all { variant ->// assign different version code for each outputvariant.outputs.each { output ->output.versionCodeOverride =project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode}}}

很多其它參考

  • 安卓so库你应该注意的事
    (http://www.voidcn.com/blog/u013278099/article/p-4944290.html)

  • Android开发,不可不知的so文件知识大全
    http://alphayang.community/2015/11/27/so-files-guide/

  • 与 .so 有关的一个长年大坑
    https://zhuanlan.zhihu.com/p/21359984

  • Android jniLibs下文件夹具体解释(.so文件)
    http://www.jianshu.com/p/b758e36ae9b5

  • ARM内核全解析,从ARM7,ARM9到Cortex-A7,A8,A9,A12,A15到Cortex-A53,A57
    http://www.myir-tech.com/resource/448.asp

  • ARM architecture
    https://en.wikipedia.org/wiki/ARM_architecture

  • android的armeabi和armeabi-v7a
    http://gybin.iteye.com/blog/2031565

版权声明:本文为【欧阳鹏】原创文章。欢迎转载,转载请注明出处! 【http://blog.csdn.net/ouyang_peng/article/details/51168072】

转载于:https://www.cnblogs.com/wzzkaifa/p/7397732.html

我的Android进阶之旅------gt;Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题...相关推荐

  1. 【我的Android进阶之旅】Android 混淆文件资源分类整理之二:将混淆文件拆分成更小粒度的混淆文件

    在我2017年的文章[我的Android进阶之旅]Android 混淆文件资源分类整理中,我已经提及过. 之前将所有的混淆都配置在一个 proguard-rules.pro 这个Android Stu ...

  2. 【我的Android进阶之旅】Android混淆踩坑之各模块各自单独配置混淆,但是将minifyEnabled设置为true导致的编译错误

    一.背景描述 在之前的两篇文章中 [我的Android进阶之旅]Android 混淆文件资源分类整理 [我的Android进阶之旅]Android 混淆文件资源分类整理之二:将混淆文件拆分成更小粒度的 ...

  3. 【我的Android进阶之旅】Android使用JNI的时候报native crash: A/libc: Fatal signal 4 (SIGILL), code 2 (ILL_ILLOPN)

    一.问题描述 最近在JNI开发中,[我的Android进阶之旅]Android 如何防止 so库文件被未知应用盗用? 抛了一个异常,然后运行的时候报如下所示的错误: 2021-01-08 14:25: ...

  4. 我的Android进阶之旅------gt;Android字符串资源中的单引號问题error: Apostrophe not preceded by 的解决的方法...

    刚刚在string字符串资源文件里,写了一个单引號.报错了,错误代码例如以下 error: Apostrophe not preceded by \ (in OuyangPeng's blog ) 资 ...

  5. 我的Android进阶之旅------gt;Android APP终极瘦身指南

    首先声明,下面文字转载于: APK瘦身实践 http://www.jayfeng.com/2015/12/29/APK%E7%98%A6%E8%BA%AB%E5%AE%9E%E8%B7%B5/ APP ...

  6. 我的Android进阶之旅------gt;Android使用AlarmManager全局定时器实现定时更换壁纸

    该DEMO将会通过AlarmManager来周期的调用ChangeService,从而让系统实现定时更换壁纸的功能. 更换壁纸的API为android.app.WallpaperManager,它提供 ...

  7. 我的Android进阶之旅------解决Android Studio编译后安装apk报错:The APK file does not exist on disk...

    1.错误描述 今天用Android Studio编译应用后安装APK的时候,报错了,错误如下所示: The APK file build\outputs\apk\OYP_2.3.4_I2Base_64 ...

  8. 我的Android进阶之旅------gt;Android自定义View来实现解析lrc歌词并同步滚动、上下拖动、缩放歌词的功能...

    前言 一LRC歌词文件简介 1什么是LRC歌词文件 2LRC歌词文件的格式 LRC歌词文件的标签类型 1标识标签 2时间标签 二解析LRC歌词 1读取出歌词文件 2解析得到的歌词内容 1表示每行歌词内 ...

  9. 我的Android进阶之旅------gt;Android实现音乐示波器、均衡器、重低音和音场功能...

    本实例来自于<疯狂Android讲义>.要实现详细的功能,须要了解下面API: MediaPlayer  媒体播放器 Visualizer 频谱 Equalizer 均衡器 BassBoo ...

最新文章

  1. 在Windows 8.1上使用Fiddler重定向http请求进行前端调试
  2. 在公司中,如何提升自己的段位,脱颖而出
  3. ArcGIS工具备忘
  4. django安装--mac系统
  5. Windows Azure Cloud Service (27) 在Windows Azure发送邮件(上)
  6. centos ffmpeg m3u8切片相关
  7. java哈希_Java Hashtable 类
  8. html下拉列表用ul,Vue.js做select下拉列表的实例(ul-li标签仿select标签)
  9. UCScript——C++集成脚本
  10. 在线修改Schema
  11. 哈尔滨工程大学ACM预热赛(A,C,H,I)
  12. 《自己动手做交互系统》——1.2 制作过程
  13. 阿里云 ubuntu 安装 curl
  14. 求样本方差,标准差,matlab
  15. 校验子解码问题(Syndrome Decoding)
  16. 【超详细】QQ空间说说爬取教程(看看你的女神在想什么~
  17. Ajax传参里面含有特殊字符
  18. linux中exec的用法
  19. 腾讯云从业者认证考试(学习笔记知识总结-全部章节)
  20. 梅科尔工作室-梁嘉莹-鸿蒙笔记1

热门文章

  1. h5打开麦克风权限录音_手机使用应用时总是需要获取权限,这3个权限不能随意给,望周知...
  2. python中mainloop什么意思_很难理解python中的Tkinter mainloop()
  3. linux:scp命令
  4. java中sql去除游标_java.sql.SQLException:-ORA-01000:已超过最大打开游标
  5. java如何跳出循环6,Java循环结结构
  6. datalistcp.class.php,Web_PHP_DedeCMS_datalistcp.class.php 动态分页类使用案例;
  7. 用java实现冒泡排序_Java实现冒泡排序
  8. c语言实训模块化程序设计,C语言 实验三 模块化程序设计.doc
  9. 并联串联混合的电压和电流_电流互感器一次绕组串联、并联,二次绕组串联、并联的相关问题...
  10. docker安装flowable-ui