Android 關於 so 檔案的總結

蘆葦科技App技術團隊發表於2019-02-16

我們在專案的開發過程中,避免不了的是引入一些第三方的應用,如果是開源的三方,那麼風險還是比較好把控的,若是一些商用的 SDK 那麼就要小心了,難免會遇到說在其他的手機上執行沒有問題,但是在華為 Mate 8 上執行卻有問題的情況。大概情況如下描述:

問題及解決方案

描述

  • 第一個專案 libs 檔案中有 arm64-v8a、armeabi、armeabi-v7a
  • 第二項專案 libs 檔案中有 armeabi、armeabi-v7a、x86
  • 第二個專案依賴第一個專案
  • 小米 4 手機手機執行 APP 沒 bug,而華為 Mate 8 手機執行 APP 出現閃退 bug
    image

解決方案

由於第一個專案是個第三方,因此需要到第三方官網中去下載 x86 的相關 so 檔案,放在 x86 目錄下,把 arm64-v8a 目錄刪除。將所有關於 so 檔案的都要保持一致,即:如果你要新增一個 armeabi-v8a 目錄,下面放第三方的 armeabi-v8a 相關的so檔案,那麼你其他的 so 檔案都要有相應想 armeabi-v8a 版本,不然就會報錯。

image

應用程式二進位制介面(ABI:Application Binary Interface)

  • 定義了二進位制檔案(如:.so 檔案)如何執行在相應的系統平臺上,從使用的指令集,記憶體對齊到可用的系統函式庫。在 Android 系統上,每一個 CPU 架構對應一個 ABI:armeabi,armeabi-v7a,x86,arm64-v8a,x86_64

CPU 型別

指令集 廠商 位數 描述
arm64-v8a ARM 64 第 8 代,64 位 ARM 處理器,很少裝置,如:三星 Galaxy S6、華為 Mate 8
armeabiv-v7a ARM 32 第 7 代及以上的 ARM 處理器。2011 年以後,大部分的生產的 Android 裝置都使用它(目前主流)
armeabiv ARM 32 第 5、6 代的 ARM 處理器,早期的手機使用的比較多
x86 Intel 32 平板、模擬器(x86裝置也支援armeabi-v7a和armeabi)
x86_64 Intel 64 64 位的平板
  • Intel 64 指令集在 x86基礎上擴充套件的
  • armabi 是針對舊的或者普通的ARM v5 CPU
  • armabi-v7a 是針對ARM v7 CPU
  • arm64-v8a 是針對最新的 ARM v8a CPU的。

.so 檔案的重要性

如果專案中使用到了 NDK,它將會生成 .so 檔案,因此顯然你已經在關注它了。如果只是使用 Java 語言進行編碼,你可能在想不需要關注 .so 檔案了吧,因為 Java 是跨平臺的。但事實上,即使你在專案中只是使用 Java 語言,很多情況下,你可能並沒有意識到專案中依賴的函式庫或者引擎庫裡面已經嵌入了 .so 檔案,並依賴於不同的ABI。 例如,專案中使用 RenderScript 支援庫,OpenCV,Unity,android-gif-drawable,SQLCipher 等,你都已經在生成的APK檔案中包含.so檔案了,而你需要關注.so檔案。 Android 應用支援的ABI取決於APK中位於lib/ABI目錄中的.so檔案,其中ABI可能是上面說過的幾個 ABI 中的一種。

相容問題

arm64-v8a 是可以向下相容的,但前提是我們專案裡面是沒有 arm64-v8a 檔案的。

  • 問題:假如有兩個資料夾 arm64-v8a 和 armeabi,armeabi 資料夾裡面有兩個檔案 a.so 和 b.so,而 arm64-v8a 中只有 a.so 檔案,那麼 arm64-v8a 的手機在用到 b.so 檔案的時候,發現 arm64-v8a 資料夾裡面沒有該檔案,那麼就會報錯。
  • 解決方法:
    • 刪除掉 arm64-v8a 資料夾;當 arm64-v8a 型別的手機發現沒有 arm64-v8a 資料夾的時候就會去 armeabi 資料夾中去找 b.so 檔案。
    • armeabi 裡面有的 so 庫,arm64-v8a 裡面也必須有,兩個資料夾裡面的檔案保持一致

注意點

  • 所有的x86/x86_64/armeabi-v7a/arm64-v8a裝置都支援armeabi架構的.so檔案
  • 只保留 armeabi-v7a 中的 so 檔案,而移除其他的 ABI 的 so 檔案,可以減小 apk 體積,但會影響到函式庫的效能和相容性。如:64位裝置(arm64-v8a, x86_64, mips64)能夠執行32位的函式庫,但是以32位模式執行,在64位平臺上執行32位版本的 ART 和 Android 元件,將丟失專為 64 位優化過的效能(ART,webview,media等等)。
  • 對只提供 armeabi 版本的第三方 .so,原樣複製一份到 armeabi-v7a 資料夾

作者介紹

  • 陳堅潤:廣州蘆葦科技 APP 團隊 Android 開發工程師

內推資訊

  • 我們正在招募小夥伴,有興趣的小夥伴可以把簡歷發到 app@talkmoney.cn,備註:來自掘金社群
  • 詳情可以戳這裡--> 廣州蘆葦資訊科技

相關文章