Android arm64-v8a、armeabi-v7a、armeabi详解
一、架構介紹
早期的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上
那我們該如何適配呢?給出如下幾個方案:
優點:基本上適配了全部CPU架構(除了淘汰的mips和mips_64)
缺點:性能低,相當于在絕大多數手機上都是需要輔助ABI或動態轉碼來兼容
同理方案一,只是又篩掉了一部分老舊設備,在性能和兼容二者中比較平衡
優點: 性能最佳
缺點: 只能運行在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 truereset()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 配置,來避免一些未知的錯誤
這樣配置會將armeabi,armeabi-v71,arm64-v8a這3個包下的so庫都打包到一個apk,而不像splits會每一個包打一個apk.
總結
以上是生活随笔為你收集整理的Android arm64-v8a、armeabi-v7a、armeabi详解的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Unity2021如何设置中文模式
- 下一篇: 【原创】oracle的tpc-c测试及方
