天天看點

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

早期的android系統幾乎隻支援armv5的cpu架構,而現在它可以支援7種,幾乎涵蓋了市面上大部分的cpu架構。

android系統目前支援的cpu架構主要包含以下7種:armv5,armv7 (從2010年起),x86 (從2011年起),mips (從2012年起),armv8,mips64和x86_64 (從2014年起),每一種都關聯着一個相應的abi。

應用程式二進制接口(application binary interface)定義了二進制檔案(尤其是.so檔案)如何運作在相應的系統平台上,從使用的指令集,記憶體對齊到可用的系統函數庫。在android中調用動态庫檔案(*.so)都是通過jni的方式。形如我們常見的:

在android系統上,每一個cpu架構對應一個abi:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

比較常見的百度地圖等sdk一般都會提供好幾套的架構庫。

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

說了這麼多,那麼如何在android平台上生成.so檔案呢?

下載下傳ndk

在android studio上下載下傳即可。下載下傳完後可以在structs目錄檢視。

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

打開項目根目錄的local.properties檔案

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

打開項目根目錄的gradle.properties檔案,添加

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

這樣ndk環境就搭建好了。

1 . 建立一個java類,以實作jni調用。

然後make project,完成後便生成位元組碼檔案。

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案
Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

2 . 根據jniutil.class生成.h檔案

打開android studio的terminal,執行以下指令:

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

執行上述指令後便會在app/src/main目錄下自動建立一個包含.h檔案的jni檔案夾。

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

我們直接打開檔案:

3 . 編寫.c檔案(jniutil.c)

這裡的jniutil檔案名需要和jniutil類中system.loadlibrary("jniutil");的參數一緻。

jniutil.c具體的編寫可根據自己的業務實作,這裡僅做測試:

注:這裡需要注意包名的統一。

4 . 配置項目app目錄下的build.gradle檔案

其中ndk标簽是新添加的,modulename 的值同樣為system.loadlibrary("jniutil");的參數。由于配置了abifilters,則隻會得到armeabi、x86、armeabi-v7a三種abi對應的.so檔案。

最後還需要在生成的jni檔案夾下建立一個空的util.c檔案,否則會有如下異常:

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

完成以上操作後,jni檔案的目錄如下:

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

其實到這一步就已經完成了,那麼我們怎麼驗證我們是否成功的建立了.so檔案呢?現在我們來測試一下,寫個textview顯示一下調用的c:

Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案
Android之.so檔案奇巧淫技.so檔案的前世今生Android平台生成.so檔案

當你編譯.so檔案時,經常會出現一些錯誤,其中最多的是"unsatisfiedlinkerror","dlopen: failed"以及其他類型的crash或者低下的性能:

ndk平台不是向後相容的,而是向前相容的,推薦使用app的minsdkversion對應的編譯平台。

這個就好比32位的軟體沒辦法運作在64位的cpu上,必須為每一個cpu架構提供一套.so檔案。