Android | 關於Android SO庫

關於So庫需要知道的知識
Android 關於arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容問題
Android 中動態加載 so 文件
一種在Native層動態加載SO庫的方案
在Android中使用dlopen加載so庫
Android Studio如何把so庫編譯進apk中

一、什麼是CPU架構以及ABI

ABI(Application Binary Interface)應用程序二進制接口。
定義了二進制文件(SO庫)如何運行在相應的CPU架構上。
從使用的指令集、內存對齊到可用的系統函數庫。

Android系統目前支持以下七種不同的CPU架構:

  • ARMv5 ARMv7 x86 MIPS ARMv8 MIP64和x86_64
  • 在Android系統上,每一個CPU架構對應一個ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

爲什麼需要重點關注.SO庫

  • 如果項目中使用到了NDK,它將會生成.so文件。
  • 很多情況下,你的項目會引用到一些So庫。
  • 很多設備都支持多於一種的ABI,例如ARM64和x86設備也可以同時運行armeabi-v7a和armeabi的二進制包。
  • 但最好是針對特定平臺提供相應平臺的二進制包。

二、SO庫應該放在什麼地方

  • Android Studio工程放在main/jniLibs/ABI目錄中(當然也可以通過在build.gradle文件中的設置jniLibs.srcDir屬性自己指定)

Android Studio如何把so庫編譯進apk中.

  • 在build.gradle的android裏,加上
  • 就會將libs下的ABI的so庫打包到APK中。
sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

打包到APK後:

  • 最終APK文件中的lib/ABI目錄中
    • /lib//lib.so

三、過濾架構

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a' //, 'armeabi', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'
        }
    }
}

四、System.load(lib)動態加載SO庫

動態加載即我們不將所需 so 庫直接拷貝到 apk 包裏面。
而是將so庫放到雲端。
先判斷用戶的手機 CPU 架構,再通過某種策略選擇合適的時間去雲端下載該用戶手機最優 ABI 架構的 so 庫文件到本地。
再需要使用通過System.load(lib)動態加載SO庫。

好處:

  • 降低了APK包的大小;
  • 動態更新 so 庫,比如我們給 so 一個版本號來控制 so 的更新工作;
  • 可以更大粒度的實現兼容,不僅僅只針對 ABI 類型,還可以針對 SDK 版本,手機上下文等加載定製版 so 庫

五、Native層加載so庫

爲什麼需要Native加載呢?

  • Native層代碼膨脹,通過SO庫來劃分模塊。
  • 簡化Java層和C++層的通信。

Native層的so庫動態加載的實現?

  • 本質上和C++動態加載DLL是一致的。
  • 先調用dlopen()函數,這個函數所需的參數,一個是so庫的路徑,一個是加載模式。
  • 在上一步得到so庫句柄之後,這時就可以調用dlsym()函數,傳入so庫句柄和所需的函數或變量名稱,返回相應的函數指針或變量指針
  • so庫的調用結束,調用dlclose()函數關閉卸載so庫;
  • 如果在打開關閉so庫,或者獲取so庫裏操作對象的指針出現錯誤的時候,可以調用dlerror()函數獲取具體的錯誤原因。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章