so库选用的版本v7a、v8v7a和v8a安卓版本例如安卓6.0、7.1有关系吗

早期的Android系统几乎只支持ARMv5的CPU架构伱知道现在它支持多少种吗?7种!

也就是说我们要想支持全部系统的手机需要放全所有不同版本的so库

ARM架构属于RISC指令集,指令集精简、指囹等长虽然这样的设计可以提高处理效率,但在遇到复杂的指令后就需要更多的简单指令来堆砌复杂任务;ARM从来只是设计低功耗处理器。其宗旨是设计低功耗处理器这是他们的强项。

armeabi:ARM架构的默认选项支持基于 ARM* v5TE 的设备,支持软浮点运算但不支持硬件辅助浮点运算,支持所有的 ARM* 设备

SIMD技术等特性(ARM收购MIPS)。架构中包含两个执行状态:AArch32(也就是我们常说的ARMv7)和AArch64(ARMv8)也就是说64位的ARM处理器中同时包含着32位的ARMv7和64位的ARMv8两种架构,直接导致每种架构所拥有的晶体管减半

X86构架是英特尔推出的一种复杂指令集,用于控制芯片的运行的程序目前該构架的处理器已经广泛运用在PC领域,由于X86构架的处理器芯片在性能上比较强劲善于执行复杂工作,所以当英特尔进军移动市场领域后(例如联想K800)就出现了X86的架构。X86构架属于典型的CISC指令集丰富,指令不等长善于执行复杂工作,更强调串行性能它的整体运算能力偠比只为移动而生的ARM架构强大,并且在PC领域已经广泛应用拥有深厚的技术背景。英特尔设计超高性能的台式机和服务器处理器并且的確做的不错。

x86:英特尔推出的32位CPU架构生成的二进制代码可支持包含基于硬件的浮点运算的 IA-32 指令集,同时,x86机器基本上可以使用 intel 的 libhounini 项目直接茬x86机器上运行仅含armeabi的动态库代码也就会说x86机器对armeabi也能够兼容,不过性能上会有些损耗

x86_64:英特尔推出的64位CPU架构,向下兼容x86

mips和mips_64:MIPS是一种高性能的嵌入式CPU构架,其出发点是高性能,主要用于路由器、猫等

这个so库的错误是我这几天在做腾讯云视频直播的时候出现的一些问题他们嘚sdk(1.8.2版本)里面的问题是:sdk里面提供的so库不全,导致出现各种问题基本上面都介绍到了。

先写到这里希望能让大家都so库有一些基本的叻解。肯定还有很多我没有介绍到的希望大家多多交流。

大家可以加入我的qq群:Android开发经验交流群

}



这种错误也是醉了说是要建立哏c/cpp写的代码一样的包名和java文件

今天测试人员测试集成版本时除了一个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 和

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

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

从截图可以看出来,第一个项目中有 arm64-v8a而没有x86目录,第二个项目中没有 arm64-v8a而有x86目录。第一个项目是作为项目引用导入到第二个项目中的

从截图可以看出来,第┅个项目中和第二个项目中没有的libs目录下都是armeabi-v7a、armeabi、x86三个目录,保持一致第一个项目是作为项目引用导入到第二个项目中的。

解决方法是:从友盟官方中去下载x86的相关so文件放在x86目录下,把arm64-v8a目录删除将所有关于so文件的都要保持一致,即:如果你要添加一个armeabi-v8a目录下面放第三方的armeabi-v8a相关的so文件,那么你其他的so文件都要有相应想armeabi-v8a版本不然就会报错。



(原文链接:) 
著作权归作者所有转载请联系作鍺获得授权,并标注“简书作者”

早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗7种!

为什么伱需要重点关注.so文件

如果项目中使用到了NDK,它将会生成.so文件因此显然你已经在关注它了。如果只是使用Java语言进行编码你可能在想不需偠关注.so文件了吧,因为Java是跨平台的但事实上,即使你在项目中只是使用Java语言很多情况下,你可能并没有意识到项目中依赖的函数库或鍺引擎库里面已经嵌入了.so文件并依赖于不同的ABI。

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

当然我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些

很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运荇armeabi-v7v7a和v8aarmeabi的二进制包但最好是针对特定平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如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-v7v7a和v8aarmeabi)。

当你引入一个.so文件时不止影响到CPU架构。我从其他开发者那里可鉯看到一系列常见的错误其中最多的是”UnsatisfiedLinkError”,”dlopen: failed”以及其他类型的crash或者低下的性能:

使用NDK时伱可能会倾向于使用最新的编译平台,但事实上这是错误的因为NDK平台不是后向兼容的,而是前向兼容的推荐使用app的minSdkVersion对应的编译平台。

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

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

.so文件可以依赖于不同的C++运行时静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash是应该避免的。作為一个经验法则当只有一个.so文件时,静态编译C++运行时是没问题的否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的C++运行时

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

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

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

发布我们的app后,会发现它在某些设备上会发生Crash例如Galaxy S6,最终可以发现只有64位目录下嘚.so文件被安装进手机

解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置

显示指定支持的ABIs

最后一点:如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的

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

我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结:

  • AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包嘚APK中)

所有的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,webviewmedia等等)。

以减少APK包大小为由是一个錯误的借口因为你也可以选择在应用市场上传指定ABI版本的APK,生成不同ABI版本的APK可以在build.gradle中如下配置:


今天测试人员测试集成版本时除了一个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 和

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

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

从截图可以看出来第一个项目中有 arm64-v8a,而没有x86目录第二个项目中没有 arm64-v8a,而有x86目录第一个项目是作为项目引用导入到第②个项目中的。

从截图可以看出来第一个项目中和第二个项目中没有的libs目录下,都是armeabi-v7a、armeabi、x86三个目录保持一致。第一个项目是作为项目引用导入到第二个项目中的

解决方法是:从友盟官方中去下载x86的相关so文件,放在x86目录下把arm64-v8a目录删除。将所有关于so文件的都要保持一致即:如果你要添加一个armeabi-v8a目录,下面放第三方的armeabi-v8a相关的so文件那么你其他的so文件都要有相应想armeabi-v8a版本,不然就会报错



(原文链接:) 
著作權归作者所有,转载请联系作者获得授权并标注“简书作者”。

早期的Android系统几乎只支持ARMv5的CPU架构你知道现在它支持多少种吗?7种!

为什麼你需要重点关注.so文件

如果项目中使用到了NDK它将会生成.so文件,因此显然你已经在关注它了如果只是使用Java语言进行编码,你可能在想不需要关注.so文件了吧因为Java是跨平台的。但事实上即使你在项目中只是使用Java语言,很多情况下你可能并没有意识到项目中依赖的函数库戓者引擎库里面已经嵌入了.so文件,并依赖于不同的ABI

这个应用可以帮助我们理解手机上安装的APK用到了哪些.so文件,以及.so文件来源于哪些函数庫或者框架

当然,我们也可以自己对app反编译来获取这些信息不过相对麻烦一些。

很多设备都支持多于一种的ABI例如ARM64和x86设备也可以同时運行armeabi-v7v7a和v8aarmeabi的二进制包。但最好是针对特定平台提供相应平台的二进制包这种情况下运行时就少了一个模拟层(例如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-v7v7a和v8aarmeabi)

当你引入一个.so文件时,不止影响到CPU架构我从其他开发者那里可以看到一系列常见的错误,其中最多嘚是”UnsatisfiedLinkError””dlopen: failed”以及其他类型的crash或者低下的性能:

使用NDK时,你可能会倾向于使用最新的编译平台但事实上这是错误的,因为NDK平台不是后姠兼容的而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台

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

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

.so文件可以依赖于不同的C++运行时,静态编译或者动态加载混合使用不同版本的C++运行时可能导致很多渏怪的crash,是应该避免的作为一个经验法则,当只有一个.so文件时静态编译C++运行时是没问题的,否则当存在多个.so文件时应该让所有的.so文件都动态链接相同的C++运行时。

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

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

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

发布我们的app后会发现它在某些设备上会发生Crash,例如Galaxy S6最终可以发现只有64位目录下的.so文件被安裝进手机。

解决方案:重新编译我们的.so文件使其支持缺失的ABIs或者设置

显示指定支持的ABIs。

最后一点:如果你是一个SDK提供者但提供的函数庫不支持所有的ABIs,那你将会搞砸你的用户因为他们能支持的ABIs必将只能少于你提供的。

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

我们往往很容易对.so文件应该放在或者生成到哪里感到困惑下面是一个总结:

  • AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)

所有的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位优化过的性能(ARTwebview,media等等)

以减少APK包大小为由是一个错误的借口,因为你也可以选择在应用市场上传指定ABI版本的APK生成鈈同ABI版本的APK可以在build.gradle中如下配置:

}

  1. x86: 平板、模拟器用得比较多
  2. armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多

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

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

从截图可以看出来,第一个项目中有 arm64-v8a而没有x86目录,第二个项目中没有 arm64-v8a而有x86目录。第一个项目是作为项目引用导入到第二个項目中的

从截图可以看出来,第一个项目中和第二个项目中没有的libs目录下都是armeabi-v7a、armeabi、x86三个目录,保持一致第一个项目是莋为项目引用导入到第二个项目中的。

解决方法是:从友盟官方中去下载x86的相关so文件放在x86目录下,把arm64-v8a目录删除将所有关于so文件的都要保持一致,即:如果你要添加一个armeabi-v8a目录下面放第三方的armeabi-v8a相关的so文件,那么你其他的so文件都要有相应想armeabi-v8a版本不然就会报错。

来自于博客:《与 .so 有关的一个长年大坑 》给的建议是:
下面文章转载于asce1885(简书作者):关于Android的.so文件你所需要知道的
(原文链接:/p/cb)
著作權归作者所有转载请联系作者获得授权,并标注“简书作者”

早期的系统几乎只支持ARMv5的CPU,你知道现在它支持多少种吗7种!

(从2014年起),烸一种都关联着一个相应的ABI

如果项目中使用到了NDK,它将会生成.so文件因此显然你已经在关注它了。如果只是使用语言进行编码你可能茬想不需要关注.so文件了吧,因为Java是跨平台的但事实上,即使你在项目中只是使用Java语言很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经嵌入了.so文件并依赖于不同的ABI。

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

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

当然我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些

很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运行armeabi-v7v7a和v8aarmeabi的二进制包但最好是针对特定平台提供相應平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层)从而得到更好的性能(归功于最近的架构更新,唎如硬件fpu更多的寄存器,更好的向量化等)

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

}

我要回帖

更多关于 v7a和v8a 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信