Android SO 文件的兼容和適配

作者:D_clock愛吃蔥花
責編:CSDN唐小引

開發 Android 應用時,有時候 Java 層的編碼不能滿足實現需求,就需要到 C/C++實現後生成 SO 文件,再用 System.loadLibrary()加載進行調用,這裏成爲 JNI 層的實現。常見的場景如:加解密算法,音視頻編解碼等。在生成 SO 文件時,需要考慮適配市面上不同手機 CPU 架構,而生成支持不同平臺的 SO 文件進行兼容。目前 Android 共支持七種不同類型的 CPU 架構,分別是:ARMv5,ARMv7 (從 2010 年起),x86 (從 2011 年起),MIPS (從 2012 年起),ARMv8,MIPS64 和 x86_64 (從 2014 年起)。如果你要完美兼容所有類型的手機,理論上是要在的 libs 目錄下放置各個架構平臺的 SO 文件。

這樣一來,雖然可以兼容所有機型,但你的項目體積也會變得非常龐大。是否一定需要帶入這麼多 SO 文件去兼容呢?答案是否定的。

SO(CPU)的兼容

對於 CPU 來說,不同的架構並不意味着一定互不兼容,根據目前 Android 共支持七種不同類型的 CPU 架構,其兼容特點可總結如下:

  • armeabi 設備只兼容 armeabi;
  • armeabi-v7a 設備兼容 armeabi-v7a、armeabi;
  • arm64-v8a 設備兼容 arm64-v8a、armeabi-v7a、armeabi;
  • X86 設備兼容 X86、armeabi;
  • X86_64 設備兼容 X86_64、X86、armeabi;
  • mips64 設備兼容 mips64、mips;
  • mips 只兼容 mips;

根據以上的兼容總結,我們還可以得到一些規律:

  • armeabi 的 SO 文件基本上可以說是萬金油,它能運行在除了 mips 和 mips64 的設備上,但在非 armeabi 設備上運行性能還是有所損耗;
  • 64 位的 CPU 架構總能向下兼容其對應的 32 位指令集,如:x86_64 兼容 X86,arm64-v8a 兼容 armeabi-v7a,mips64 兼容 mips;

關於 SO 的兼容規律就介紹到此,下面談談適配工作。

SO 的適配

從目前移動端 CPU 市場的份額數據看,ARM 架構幾乎壟斷,所以,除非你的用戶很特殊,否則幾乎可以不考慮單獨編譯帶入 X86、X86_64、mips、mips64 架構 SO 文件。除去這四個架構之後,還要帶入 armeabi、armeabi-v7a、arm64-v8a 這三個不同類型,這對於一個擁有大量 SO 文件的應用來說,安裝包的體積將會增大不少。

針對以上情況,我們可以應用的設備分佈和市場情況再進行取捨斟酌,如果你的應用仍有不少 armeabi 類型的設備,可以考慮只保留 armeabi 目錄下的 SO 文件(萬金油特性)。但是,儘管 armeabi 可以兼容多種平臺,仍有些運算在 armeabi-v7a、arm64-v8a 去使用 armeabi 的 SO 文件時,性能會非常差強人意,所以還是應該用其對應平臺架構的 SO 文件進行運算。注意,這裏並不是要帶多一整套 SO 文件到不同的目錄下,而是將性能差異比較明顯的某個 armeabi-v7a、arm64-v8a 平臺下的 SO 文件放到 armeabi 目錄,然後通過代碼判斷設備的 CPU 類型,再加載其對應架構的 SO 文件,很多大廠的應用便是這麼做的。如微信的 lib 下雖然只有 armeabi 一個目錄,但目錄內的文件仍放着 v5、v7a 架構的 SO 文件,用於處理兼容帶來的某些性能運算問題。

就目前市場份額而言,絕大部分的設備都已經是 armeabi-v7a、arm64-v8a,你也可以考慮只保留 armeabi-v7a 架構的 SO 文件,這樣能獲得更好的性能效果。

總結

以上便是關於 SO 文件兼容適配的一點總結梳理,如有錯誤,歡迎指出。

參考文章

發佈了216 篇原創文章 · 獲贊 114 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章