Android arm64-v8a、armeabi-v7a、armeabi详解「建议收藏」

一、架构介绍早期的Android系统几乎只支持ARMv5的CPU架构,后面发展到支持七种不同的CPU架构:ARMv5,ARMv7(从2010年起),x86(从2011年起),MIPS(从2012年起),ARMv8,MIPS64和x86_64(从2014年起),每一种都关联着一个相应的ABI。应用程序二进制接口(ApplicationBinaryInterface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android系

大家好,又见面了,我是你们的朋友全栈君。

一、架构介绍

早期的Android系统几乎只支持ARMv5的CPU架构,后面发展到支持七种不同的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。
但是最新的谷歌官方文档已经把mips和armv5移除了,如图所示:
在这里插入图片描述

  • x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现 对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的
  • armeabi: ARM v5 这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈
  • armeabi-v7a: ARM v7
  • arm64-v8a: 64位支持,目前主流的版本,虽然网上很多博客都说v7是主流版本,但是我亲自试验了很多手机,都是arm64-v8a的架构,测试机型包括小米5-小米9,华为P30,华为mate10,魅蓝2等均是v8架构

查询手机cpu命令行:

adb shell getprop ro.product.cpu.abi

二、ABI是如何工作的

一个Android设备可以支持多种ABI,设备主ABI和辅助ABI,以arm64-v8a为主ABI的设备,辅助ABI为armeabi-v7a和armeabi,以armeabi-v7a为主ABI的设备,辅助ABI为armeabi。
另外,x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现对 arm .so 的兼容,也就是说有适配armeabi平台的APP是可以跑在x86手机上的。

三、ABI具体适配流程

在这里插入图片描述
对于一个cpu是arm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,先看有没有arm64-v8a文件夹,如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常;
如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到想要的.so文件,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。

四、项目中该如何适配

Q1: 只适配了armeabi-v7a,那如果APP装在其他架构的手机上,如arm64-v8a上,会蹦吗?
A: 不会,但是反过来会。
因为armeabi-v7a和arm64-v8a会向下兼容:

  • 只适配armeabi的APP可以跑在armeabi,x86,x86_64,armeabi-v7a,arm64-v8上
  • 只适配armeabi-v7a可以运行在armeabi-v7a和arm64-v8a
  • 只适配arm64-v8a 可以运行在arm64-v8a上

那我们该如何适配呢?给出如下几个方案:

  1. 只适配armeabi
    优点:基本上适配了全部CPU架构(除了淘汰的mips和mips_64)
    缺点:性能低,相当于在绝大多数手机上都是需要辅助ABI或动态转码来兼容
  2. 只适配 armeabi-v7a
    同理方案一,只是又筛掉了一部分老旧设备,在性能和兼容二者中比较平衡
  3. 只适配 arm64-v8
    优点: 性能最佳
    缺点: 只能运行在arm64-v8上,要放弃部分老旧设备用户

这三种方案都是可以的,现在的大厂APP适配中,这三种都有,大部分是前2种方案。具体选哪一种就看自己的考量了,以性能换兼容就arm64-v8,以兼容换性能armeabi,二者稍微平衡一点的就armeabi-v7a。

早在今年(2019)一月份,Google 就发布通知,在今年 8 月 1 日开始,上架的 App,除了提供 32 位的版本之外,还需要提供 64 位的版本。

因此,项目之前强制只使用armeabi一种架构的方式已经不行了。
那这里说的 64 位版本支持,到底是什么?
如果你的应用,完全是使用 Java 或者 Kotlin 编写代码,不包含任何原生(Native)的支持,那么就表示这个应用已经支持 64 位。
但是应用内使用了任何原生(Native)的支持(so 库),就需要针对这些 so 文件,针对不同的 CPU 架构提供不同的版本的 so 支持。
需要注意的是,有些时候,在我们自身的代码中,确实没有用到原生的支持,但是在 App 中使用的一些第三方库中却包含了。
此时最稳妥的方式,就是针对最终打包生成的 APK 文件进行分析,来判断是否需要提供 64 位架构的支持。

五、打包配置

split分包

这个命令可以按照各种规则去分包,比如按照abi,屏幕密度(即ldpi,hdpi等)分包

splits { 
   
        abi { 
   
            enable true
            reset()
            include 'x86','armabi'
            exclude 'armeabi', 'armeabi-v7a', "arm64-v8a"
            universalApk true
        }
    }
ndk{abiFilters:}过滤

这个指令可以配置只打包你配置的so库,没有配置的就不打包,很灵活。
第三方aar文件,如果这个sdk对abi的支持比较全,可能会包含armeabi、armeabi-v7a、x86、arm64-v8a、x86_64五种abi,而你应用的其它so只支持armeabi、armeabi-v7a、x86三种,直接引用sdk的aar,会自动编译出支持5种abi的包。但是应用的其它so缺少对其它两种abi的支持,那么如果应用运行于arm64-v8a、x86_64为首选abi的设备上时,就会crash了,所以我们需要在我们的app中配置 abiFilter 配置,来避免一些未知的错误

//过滤x86的so库
ndk { 
   
    abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
}

这样配置会将armeabi,armeabi-v71,arm64-v8a这3个包下的so库都打包到一个apk,而不像splits会每一个包打一个apk.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/129130.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • FileProvider 的使用(Failed to find configured root that contains/storage/emulated/0/DCIM/ )

    FileProvider 的使用(Failed to find configured root that contains/storage/emulated/0/DCIM/ )首先扯点别的:今天不上班,在家里和剑宗喝了点酒,和同学聊了会天,也是挺开心,现在学会习。以前调用系统相机拍照的时候,流程是这样的privatevoidtakePhoto(){IntenttakePictureIntent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);if(takePictureIntent

    2022年10月29日
  • Cygwin的安装教程

    1、在官网上选择你想要的版本(www.cygwin.com)2、笔者选的是64位的3、如果网速快的话可以选择第一个选项4、选择路径5、选择你下载的地方6、这个一般都是选择直接连接的7、然后选择镜像的话推荐选择阿里的阿里云镜像http://mirrors.aliyun.com/cygwin/8、随后就是重头戏选择你要的组件包:必选(bison,flex,gcc-core,gcc-g++,make)9、在后面的skip双击就好会出现版本名10、开始下载11、最后

  • 谷歌学术介绍_谷歌学术镜像官网

    谷歌学术介绍_谷歌学术镜像官网转载自:http://blog.renren.com/share/111541487/15517062888“谷歌学术”是谷歌搜索引擎中的学术检索部分,相对于知网、维普、万方、Pubmed等专业的论文数据库来说功能单薄了些,但具有页面简约、搜索速度快、集国内外文献于一体、某些文章可直接免费下载等优点,对忙于“赶制”毕业论文的广大同学们来说的确是一个不可多得的网站!

    2022年10月11日
  • AntMessenger聊天软件_thinksns商业版破解下载

    AntMessenger聊天软件_thinksns商业版破解下载社交系统ThinkSNSPlus V2.1.0更新播报

  • pycharm中mysql连接失败_pycharm连接mysql数据库连接不上[通俗易懂]

    pycharm中mysql连接失败_pycharm连接mysql数据库连接不上[通俗易懂]代码其实很简单,只有一小段,是在pycharm上运行的,所用的python版本为2.7,mysql版本为5.7.21#-*-coding:UTF-8-*-importreimportMySQLdbif__name__==’__main__’:#打开数据库conn=MySQLdb.connect(host=’localhost’,port=3306,user=’root’,pa…

    2022年10月30日
  • java 三大特性_java的三大特性是什么?

    java 三大特性_java的三大特性是什么?java的三大特性Java语言的三大特性即是:封装、继承、多态首先先简单的说一下其3大特性的定义:封装:在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。将抽象得到的…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号