arm64-v8a、armeabi-v7a、armeabi、x86 abiFilters 详解
abiFilters的作用
在app的gradle的defaultConfig里面加上如下
ndk {abiFilters "armeabi-v7a" // 指定要ndk需要兼容的架構(gòu)(這樣其他依賴包里mips,x86,armeabi,arm-v8之類的so會被過濾掉) }一. lib和libs
放在lib中的是被reference的,放在libs中的是被include的。
放在libs中的文件會自動被編輯器所include。所以不要把API放到libs里去。
lib的內(nèi)容是不會被打包到APK中,libs中的內(nèi)容是會被打包進(jìn)APK中
二. .so庫
NDK編譯出來的動態(tài)鏈接庫。
一些重要的加密算法或者核心協(xié)議一般都用c寫然后給java調(diào)用。這樣可以避免反編譯后查看到應(yīng)用的源碼。
三. .so庫該如何存放
放置 .so 文件的正確姿勢其實(shí)就兩句話:
? 為了減小 apk 體積,只保留 armeabi 和 armeabi-v7a 兩個文件夾,并保證這兩個文件夾中 .so 數(shù)量一致
? 對只提供 armeabi 版本的第三方 .so,原樣復(fù)制一份到 armeabi-v7a 文件夾
存放so的規(guī)則:
你應(yīng)該盡可能的提供專為每個ABI優(yōu)化過的.so文件,但要么全部支持,要么都不支持:你不應(yīng)該混合著使用。你應(yīng)該為每個ABI目錄提供對應(yīng)的.so文件。
關(guān)于存放的問題,可以看看這篇
四. libs下armeabi等的作用是什么
存放.so庫,主要針對不同的設(shè)備兼容,也可以說是專門針對不同Android手機(jī)下CPU架構(gòu)的兼容。
下面就來扯一下安卓cpu
Android 設(shè)備的CPU類型(通常稱為”ABIs”)
架構(gòu)介紹
早期的Android系統(tǒng)幾乎只支持ARMv5的CPU架構(gòu),后面發(fā)展到支持七種不同的CPU架構(gòu):ARMv5,ARMv7 (從2010年起),x86 (從2011年起),MIPS (從2012年起),ARMv8,MIPS64和x86_64 (從2014年起),每一種都關(guān)聯(lián)著一個相應(yīng)的ABI。
應(yīng)用程序二進(jìn)制接口(Application Binary Interface)定義了二進(jìn)制文件(尤其是.so文件)如何運(yùn)行在相應(yīng)的系統(tǒng)平臺上,從使用的指令集,內(nèi)存對齊到可用的系統(tǒng)函數(shù)庫。在Android 系統(tǒng)上,每一個CPU架構(gòu)對應(yīng)一個ABI:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。
但是最新的谷歌官方文檔已經(jīng)把mips和armv5移除了,如圖所示:
各版本分析如下:
? mips / mips64: 極少用于手機(jī)可以忽略(谷歌最新的文檔已經(jīng)不支持了)
? x86 / x86_64: x86 架構(gòu)的手機(jī)都會包含由 Intel 提供的稱為 Houdini 的指令集動態(tài)轉(zhuǎn)碼工具,實(shí)現(xiàn) 對 arm .so 的兼容,再考慮 x86 1% 以下的市場占有率,x86 相關(guān)的兩個 .so 也是可以忽略的
? armeabi: ARM v5 這是相當(dāng)老舊的一個版本,缺少對浮點(diǎn)數(shù)計算的硬件支持,在需要大量計算時有性能瓶頸
? armeabi-v7a: ARM v7
? arm64-v8a: 64位支持,目前主流的版本,雖然網(wǎng)上很多博客都說v7是主流版本,但是我親自試驗(yàn)了很多手機(jī),都是arm64-v8a的架構(gòu),測試機(jī)型包括小米5-小米9,華為P30,華為mate10,魅藍(lán)2等均是v8架構(gòu)
查詢手機(jī)cpu命令行:
- 1
無圖無真相:
只有一款不知名的oppo手機(jī),android系統(tǒng)4.3,用的是v7的架構(gòu)
ABI是如何工作的
2020.06更新, 看到一篇很好的文章搬過來了,感謝原作者(為何大廠APP如微信、支付寶、淘寶、手Q等只適配了armeabi-v7a/armeabi? - 掘金)
官方文檔解釋如下:
Android 系統(tǒng)在運(yùn)行時知道它支持哪些 ABI,因?yàn)榘姹咎囟ǖ南到y(tǒng)屬性會指示:
- 設(shè)備的主要 ABI,與系統(tǒng)映像本身使用的機(jī)器代碼對應(yīng)。
- (可選)與系統(tǒng)映像也支持的其他 ABI 對應(yīng)的輔助 ABI。
此機(jī)制確保系統(tǒng)在安裝時從軟件包提取最佳機(jī)器代碼。
為實(shí)現(xiàn)最佳性能,應(yīng)直接針對主要 ABI 進(jìn)行編譯。例如,基于 ARMv5TE 的典型設(shè)備只會定義主 ABI:armeabi。相反,基于 ARMv7 的典型設(shè)備將主 ABI 定義為 armeabi-v7a,并將輔助 ABI 定義為 armeabi,因?yàn)樗梢赃\(yùn)行為每個 ABI 生成的應(yīng)用原生二進(jìn)制文件。
64 位設(shè)備也支持其 32 位變體。以 arm64-v8a 設(shè)備為例,該設(shè)備也可以運(yùn)行 armeabi 和 armeabi-v7a 代碼。但請注意,如果應(yīng)用以 arm64-v8a 為目標(biāo),而非依賴于運(yùn)行 armeabi-v7a 版應(yīng)用的設(shè)備,則應(yīng)用在 64 位設(shè)備上的性能要好得多。
許多基于 x86 的設(shè)備也可運(yùn)行 armeabi-v7a 和 armeabi NDK 二進(jìn)制文件。對于這些設(shè)備,主 ABI 將是 x86,輔助 ABI 是 armeabi-v7a。
總的來說,就是一個Android設(shè)備可以支持多種ABI,設(shè)備主ABI和輔助ABI,以arm64-v8a為主ABI的設(shè)備,輔助ABI為armeabi-v7a和armeabi,以armeabi-v7a為主ABI的設(shè)備,輔助ABI為armeabi。
另外,x86 架構(gòu)的手機(jī)都會包含由 Intel 提供的稱為 Houdini 的指令集動態(tài)轉(zhuǎn)碼工具,實(shí)現(xiàn)對 arm .so 的兼容,也就是說有適配armeabi平臺的APP是可以跑在x86手機(jī)上的。
ABI具體適配流程
對于一個cpu是arm64-v8a架構(gòu)的手機(jī),它運(yùn)行app時,進(jìn)入jnilibs去讀取庫文件時,先看有沒有arm64-v8a文件夾,如果沒有該文件夾,去找armeabi-v7a文件夾,如果沒有,再去找armeabi文件夾,如果連這個文件夾也沒有,就拋出異常;
如果有arm64-v8a文件夾,那么就去找特定名稱的.so文件,注意:如果沒有找到想要的.so文件,不會再往下(armeabi-v7a文件夾)找了,而是直接拋出異常。
我們項(xiàng)目中該如何適配呢
Q1: 只適配了armeabi-v7a,那如果APP裝在其他架構(gòu)的手機(jī)上,如arm64-v8a上,會蹦嗎?
A: 不會,但是反過來會。
因?yàn)閍rmeabi-v7a和arm64-v8a會向下兼容:
- 只適配armeabi的APP可以跑在armeabi,x86,x86_64,armeabi-v7a,arm64-v8上
- 只適配armeabi-v7a可以運(yùn)行在armeabi-v7a和arm64-v8a
- 只適配arm64-v8a 可以運(yùn)行在arm64-v8a上
那我們該如何適配呢?給出如下幾個方案:
方案一:只適配armeabi
優(yōu)點(diǎn):基本上適配了全部CPU架構(gòu)(除了淘汰的mips和mips_64)
缺點(diǎn):性能低,相當(dāng)于在絕大多數(shù)手機(jī)上都是需要輔助ABI或動態(tài)轉(zhuǎn)碼來兼容
方案二:只適配 armeabi-v7a
同理方案一,只是又篩掉了一部分老舊設(shè)備,在性能和兼容二者中比較平衡
方案三: 只適配 arm64-v8
優(yōu)點(diǎn): 性能最佳
缺點(diǎn): 只能運(yùn)行在arm64-v8上,要放棄部分老舊設(shè)備用戶
這三種方案都是可以的,現(xiàn)在的大廠APP適配中,這三種都有,大部分是前2種方案。具體選哪一種就看自己的考量了,以性能換兼容就arm64-v8,以兼容換性能armeabi,二者稍微平衡一點(diǎn)的就armeabi-v7a。
對于64位手機(jī)跟64位處理器
ARM64位處理器和電腦的64位處理器是兩個截然不容的概念,他并不是64位就能原生向下兼容32位程序,而是通過64位處理器中集成的32位架構(gòu)來運(yùn)行32位程序。說得通俗點(diǎn),它不是以64位形態(tài)來運(yùn)行32位程序,卻是以32位的形態(tài)運(yùn)行32位程序的。
由于目前新出的64位處理器包含兩個架構(gòu),而且制程技術(shù)沒有提升(28nm),同時在手機(jī)與平板上,芯片面積有著嚴(yán)格的限定,不能過分增加,這導(dǎo)致64位ARM處理器平均分配到每個架構(gòu)的晶體管數(shù)量銳減,也就是說從64位處理器中的32位架構(gòu)方面,對于同規(guī)格的32位處理器而言,不但沒有提高,性能反而是一定規(guī)模下降的。但處理器廠家又必須給消費(fèi)者一個交代,以更好的推廣64位,所以廠家就必須在其他方面提升性能,以彌補(bǔ)CPU的晶體管數(shù)量減少帶來的損失。比如:更換性能更強(qiáng)的GPU、提升內(nèi)存帶寬、多核心虛擬單顆核心提升單核性能、聯(lián)合跑分軟件商修改跑分權(quán)重(提升GPU分?jǐn)?shù),降低CPU分?jǐn)?shù)的權(quán)重)等等。這樣,揚(yáng)長避短,最終到達(dá)消費(fèi)者手里,用跑分軟件一跑,確實(shí)有提升,用戶開心,廠家腰包也鼓了。
綜上所述,ARM64位處理器從嚴(yán)格意義來說,叫它ARM32+64更加貼切,他相對于ARM32位處理器,有倒退的地方,也有進(jìn)步的余地,但正因?yàn)榈雇思て鹆薃RM進(jìn)取的決心,讓它大刀闊斧的向前變革,不得不說也算一種進(jìn)步。但ARM64在的手機(jī)上真的有用嗎?我只能說,目前確實(shí)沒啥用,但今后或許有。(其他地方搜羅的) 綜上所述,ARM64位處理器從嚴(yán)格意義來說,叫它ARM32+64更加貼切,他相對于ARM32位處理器,有倒退的地方,也有進(jìn)步的余地,但正因?yàn)榈雇思て鹆薃RM進(jìn)取的決心,讓它大刀闊斧的向前變革,不得不說也算一種進(jìn)步。但ARM64在的手機(jī)上真的有用嗎?我只能說,目前確實(shí)沒啥用,但今后或許有。(其他地方搜羅的)
真正的64位手機(jī)并不止單純停留在處理器上,如果只因?yàn)樗奶幚砥魇?4位,就稱其為64位手機(jī)的話,我們可以毫不猶疑的說這可能是虛假宣傳,好在聯(lián)想很聰明,在發(fā)布A678t和A805e宣傳的時候,只說64位處理器手機(jī)。
“64位處理器手機(jī)”與“64位手機(jī)”是兩種天壤之別的概念:只要是處理器包含64架構(gòu)位的,就可以稱“64位處理器手機(jī)”,這種手機(jī)也許還運(yùn)行不了64位程序,只是用來搶占市場,和32位手機(jī)比起來優(yōu)勢并不明顯。
“64位手機(jī)”就不同了:它包含著64位處理器、64位標(biāo)準(zhǔn)系統(tǒng)、64位安卓虛擬機(jī)、以及64位程序,這才是真正意義上的64位手機(jī)!
谷歌官方曾說,安卓很早前就支持64位了,這話不假,從Android4.0到Android4.4,安卓系統(tǒng)都支持64位的硬件,但是這僅僅表示底層驅(qū)動支持64位,能運(yùn)行在64位的硬件之上,僅此而已。然而,上層運(yùn)行軟件的,無論是Dalvik的虛擬機(jī),還是ART虛擬機(jī)都是32位的。也就是說,只要你的手機(jī)系統(tǒng)是Android4.0—4.4,即便你的處理器是64位,也只能在32位虛擬機(jī)下運(yùn)行32位程序,就算真的64位程序擺在你眼前,也無法安裝。。
但是谷歌官方今年年初就已經(jīng)發(fā)布強(qiáng)制需要64位架構(gòu):
早在今年(2019)一月份,Google 就發(fā)布通知,在今年 8 月 1 日開始,上架的 App,除了提供 32 位的版本之外,還需要提供 64 位的版本。
因此,項(xiàng)目之前強(qiáng)制只使用armeabi一種架構(gòu)的方式已經(jīng)不行了。
那這里說的 64 位版本支持,到底是什么?
如果你的應(yīng)用,完全是使用 Java 或者 Kotlin 編寫代碼,不包含任何原生(Native)的支持,那么就表示這個應(yīng)用已經(jīng)支持 64 位。
但是應(yīng)用內(nèi)使用了任何原生(Native)的支持(so 庫),就需要針對這些 so 文件,針對不同的 CPU 架構(gòu)提供不同的版本的 so 支持。
需要注意的是,有些時候,在我們自身的代碼中,確實(shí)沒有用到原生的支持,但是在 App 中使用的一些第三方庫中卻包含了。
此時最穩(wěn)妥的方式,就是針對最終打包生成的 APK 文件進(jìn)行分析,來判斷是否需要提供 64 位架構(gòu)的支持。
打包配置
split分包
這個命令可以按照各種規(guī)則去分包,比如按照abi,屏幕密度(即ldpi,hdpi等)分包
include就是包括,exclude就是不包括。包括的配置每一個項(xiàng)都會生成一個apk包。
但是這樣配置,會生成兩個包,一個只包含x86的so庫,一個只包含armabi的so庫。,顯然不符合需求
ndk{abiFilters:}過濾
這個指令可以配置只打包你配置的so庫,沒有配置的就不打包,很靈活。
第三方aar文件,如果這個sdk對abi的支持比較全,可能會包含armeabi、armeabi-v7a、x86、arm64-v8a、x86_64五種abi,而你應(yīng)用的其它so只支持armeabi、armeabi-v7a、x86三種,直接引用sdk的aar,會自動編譯出支持5種abi的包。但是應(yīng)用的其它so缺少對其它兩種abi的支持,那么如果應(yīng)用運(yùn)行于arm64-v8a、x86_64為首選abi的設(shè)備上時,就會crash了,所以我們需要在我們的app中配置 abiFilter 配置,來避免一些未知的錯誤
//過濾x86的so庫 ndk {abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a' }這樣配置會將armeabi,armeabi-v71,arm64-v8a這3個包下的so庫都打包到一個apk,而不像splits會每一個包打一個apk.
總結(jié)
以上是生活随笔為你收集整理的arm64-v8a、armeabi-v7a、armeabi、x86 abiFilters 详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: URAL 2047 Maths 打表 递
- 下一篇: js添加收藏夹