Android ABI的淺析

原文鏈接:https://www.jianshu.com/p/d2119b3880d8

個人理解:ABI指的是armeabiv-v7a,arm64-v8a等二進制文件使用的架構,CPU支持

的架構才能正常執行

 

Android ABI的概念

ABI全稱:Application binary interface(應用程序二進制接口),定義了一套規則,允許編譯好的二進制目標代碼能在所有兼容該ABI的操作系統中無需改動就能運行。

不同的Android手機使用不同的CPU,因此需要提供對應的二進制接口交互規則(即對應的ABI文件)才能進行交互。

部分CPU是能支持多種交互規則,但這是在犧牲性能的前提下所做的兼容。

主流的ABI架構

  1. armeabiv-v7a: 第7代及以上的 ARM 處理器。2011年以後的生產的大部分Android設備都使用它。
  2. arm64-v8a: 第8代、64位ARM處理器,很少設備,三星 Galaxy S6是其中之一。
  3. armeabi: 第5代、第6代的ARM處理器,早期的手機用的比較多。
  4. x86: 平板、模擬器用得比較多。
  5. x86_64: 64位的平板。

ABI和CPU的關係

當一個應用被安裝在設備上時,只有該設備支持的CPU架構對應的.so文件會被安裝,如果支持多個ABI架構,會按照優先級進行按照

具體的支持類型如下

ARMv5(CPU):armeabi(ABI)
ARMv7:armeabi,armeabi-v7a
ARMv8:armeabi,armeabi-v7a,arm64-v8a
MIPS:mips
MIPS64:mips,mips64
x86:x86(1),armeabi(2),armeabi-v7a(3)
x86_64:armeabi,x86,x86_64

可以看出CPU大都是向前兼容的,但是選擇ABI時會有個優先級。

比如X86型的CPU,優先選擇x86目錄下的.so包,如果存在,就不會再安裝其他支持的ABI架構;如果沒有x86目錄,纔會選擇armeabi-v7a目錄下的.so,最後纔會選擇armeabi目錄下的.so文件。

ps:X86設備雖然能夠運行armeabi下的so庫,但可能會損失性能,而且不能保證一定不會發生crash,尤其是有小公司出產的so庫

使用過程中的問題

.so文件,放入了優先級低的ABI目錄

設備CPU架構是ARMv7,ABI文件是armeabi-v7a,但是放進了armeabi目錄中

1.如果項目中有armeabi-v7a目錄,目錄下沒有so庫,ARMv7優先加載armeabi-v7a目錄,發現沒有對應的so庫,會報錯。

Caused by: java.lang.UnsatisfiedLinkError

2.項目中只有armeabi的目錄,ARMv7會加載armeabi目錄,同時加載目錄下的so庫,相當於加載了一個armeabi規則的so庫,因爲向前兼容的特性,不會報錯,也能運行,但性能會損失。

.so文件放入優先級高的ABI目錄

設備CPU架構是ARMv7,ABI文件是armeabi,但是放進了armeabi-v7a目錄中下。

可以被加載,但是能不能被使用?我也不確定。因爲armeabi的so庫不一定能支持armeabi-v7a定下的接口交互規則。

多個第三方的SDK中的ABI文件優先級不一樣。

兩個第三方的SDK中ABI文件優先級不一樣,手機加載運行時,會導致優先級低的庫,無法被加載

我的手機cpu架構是ARMv7,項目中使用兩個第三方SDK:企業A和企業B

企業A:ABI文件是armeabi-v7a,放進armeabi-v7a目錄中。
企業B:ABI文件是armeabi-v5te,放進armeabi目錄中。

在運行時,會發現運行後crash,出現如下log信息。

Caused by: java.lang.UnsatisfiedLinkError

這是因爲低優先級的也就是企業B的so包沒有被加載進來,也就無法正常使用導致報錯。

解決辦法:

1、使用同一優先級的ABI文件,ABI文件放入優先級相同的ABI目錄

企業A:ABI文件是armeabi-v5te,放進armeabi目錄中。
企業B:ABI文件是armeabi-v5te,放進armeabi目錄中。

企業A:ABI文件是armeabi-v7a,放進armeabi-v7a目錄中。
企業B:ABI文件是armeabi-v7a,放進armeabi-v7a目錄中。

2、使用不同優先級的ABI文件,ABI文件放入優先級相同的ABI目錄。一般情況不建議這麼做。

企業A:ABI文件是armeabi-v7a,但是放進armeabi目錄中。
企業B:ABI文件是armeabi-v5te,放進armeabi目錄中。

企業A:ABI文件是armeabi-v7a,放進armeabi-v7a目錄中。
企業B:ABI文件是armeabi-v5te,但是放進armeabi-v7a目錄中。

so文件的重要法則

處理.so文件時有一條簡單卻並不知名的重要法則。
你應該儘可能的提供專爲每個ABI優化過的.so文件

NDK的兼容性

使用NDK時,選擇app的minsdkVersion對應的編譯平臺,因爲NDK是向後兼容的

注意事項

所有ABI文件夾提供的so要保持一致

如果我們的應用選擇了支持多個ABI,要十分注意:對於每個ABI下的so,但要麼全部支持,要麼都不支持。不應該混合着使用,而應該爲每個ABI目錄提供對應的.so文件。

參考文章

安卓app打包的時候還需要兼容armeabi麼
談談Android的so
ABI和CPU關係的疑難雜症
Android ABI概念

另外

個人的github
閒暇之餘寫的故事



作者:niknowzcd
鏈接:https://www.jianshu.com/p/d2119b3880d8
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章