相信不少人對於NDK 開發都是懵逼的,好比都知道把加密的邏輯以及密鑰放在so文件中,可是你知道怎麼生成so文件嗎?你知道開發jni嗎?你熟悉jni語法嗎?怎麼配置android studio 中的NDK環境?此時你必定很懵逼,我也是從這過來的,我不能幫助你開發Ndk,可是我可讓你不懵逼。java
有須要的能夠去百度,這裏講一下android studio。順便說一下百度上有不少很坑的文章,本身沒動手作過不知道,文章晦澀難懂,並且有些地方一言蔽之,搞不清方向,必須仔細過濾,才能發現。因此我總結了這篇文章android
1、NDK相關角色概述c++
一、NDK和SO微信
NDK 全稱 Native Development Kit,是Google在Android開發中提供的一套用於快速建立native工程的一個工具。從上圖這個Android系統框架來看,咱們上層是經過JNI方式來調用NDK層的,使用這個工具能夠很方便的編寫和調試JNI的代碼。由於架構
C語言不跨平臺,在Windows系統下使用NDK編譯在app
Linux下能執行的函數庫——SO文件,全稱Shared Objects,其實質就是一堆c、c++的頭文件和實現文件打包成一個庫。目前Android系統目前支持如下七種不一樣的CPU框架
架構,每一種對應着各自的應用程序二進制接口ABI:(Application Binary Interface)定義了二進制文件(尤爲是.so文件)如何運行在相應的系統平臺上,從使用的指令集,內存對齊到可用的系統函數庫。函數
ARMv5——armeabi工具
ARMv7 ——armeabi-v7agradle
ARMv8——arm64- v8a
x86——x86
MIPS ——mips
MIPS64——mips64
x86_64——x86_64
以本人ODM經驗來講,你應該儘量的提供專爲每一個ABI優化過的.so文件,(儘可能不要混合着使用)。你應該爲每一個ABI目錄提供對應的.so文件。當一個應用安裝在設備上,只有該設備支持的CPU架構對應的.so文件會被安裝。在x86設備上,libs/x86目錄中若是存在.so文件的 話,會被安裝,若是不存在,則會選擇armeabi-v7a中的.so文件,若是也不存在,則選擇armeabi目錄中的.so文件(由於x86設備也支 持armeabi-v7a和armeabi)。ps: Native Libs Monitor 這個應用能夠幫助咱們理解手機上安裝的APK用到了哪些.so文件,以及.so文件來源於哪些函數庫或者框架。
2、JNI
JNI 全稱
Native Inteface,即
本地接口,是Java中定義的一種用於鏈接Java和C/C++接口的一種實現方式。Java語言裝載到虛擬機中,不能和硬件交互,不能驅動開發。JNI擴展了Java虛擬機的能力,驅動開發、無線熱點共享,底層語言(C、C++)效率高,數學運算、實時渲染的遊戲,音視頻處理等等,簡而言之,就是Java代碼調用c、c++代碼,JNI模式一共涉及到三個角色:C/C++ 代碼、本地方法接口類、Java層中具體業務類
一、JNI簡要流程
二、JNI的變量類型與Java類型對比表
Java中變量的類型 | JNI對應的類型名 | C/C++變量類型 |
---|---|---|
boolean |
jboolean |
unsigned char |
float |
jfloat |
float |
double |
jdouble |
double |
byte |
jbyte |
signed char |
char |
jchar |
unsigned short |
short |
jshort |
short |
int |
jint/jsize |
int |
long |
jlong |
long long |
Object |
jobject |
void * |
String |
jstring |
void * |
三、JNI的基本語法JNIEXPORT jstring JNICALL Java_xiao_mi_jni_JNITest_getJniStr(JNIEnv *env, jclass type) { return (*env)->NewStringUTF(env, "Hello from JNI!"); }命名規則
jstring--------->返回值類型
xiao_mi_jni --->包名
JNITest--------->類名
getJniStr------->方法名
Java加載sostatic { System.loadLibrary("jnitest");//加載so文件,不要帶上前綴lib和後綴.so }ps:之前不明白上邊註釋的這句話,只有本身去看才能明白爲何,因此我用AS打開了apk,原來打包出來的都是前綴加lib後綴加.so的文件格式。
四、Gradle
Gradle 是一個基於Apache Ant和Apache Maven概念的項目自動化建構工具。它使用一種基於Groovy的特定領域語言(DSL)來聲明項目設置。以往Android NDK開發須要在Eclipse或源碼環境下,創建並配置Android.mk和Application.mk,且還要經過java命令生成.h頭文件,才能編譯生成so庫。但在Android Studio中這些步驟都不須要,由於Gradle足夠強大,只需配置Gradle便可編譯生成so庫。
3、開發JNI的步驟
JNI代碼主要又分爲Native代碼和Java代碼,因此咱們得實現Native端和Java端
一、安裝NDK配置環境變量和相關插件(NDK、CMake、LLDB)
下載完以後 會自動下載到sdk裏面
二、新建一個Android標準工程,並在工程設置中配置NDK路徑。
三、打開app下的 build.gradle,配置NDK和在gradle.properties裏配置android.useDeprecatedNdk=true defaultConfig { applicationId "xiao.mi.jni" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" ndk{ moduleName "jnitest"//*生成的so文件名,必填 abiFilters "armeabi-v7a", "x86"//配置輸出的abi體系結構下的so庫, } }
配置gradle.properties 文件
android.useDeprecatedNdk=true4.在類中定義jni本地接口方法。publicclassJNITest{ publicstaticnative String getJniStr(); publicstaticnative String processBitmap(Bitmap bitmap); }五、生成對應的C文件默認實現
在咱們定義了本地接口方法以後,咱們在方法上按alt+Enter,而後生成對應的方法,但是不出意外的話生成的c文件只是有一個頭文件的,並無爲咱們生成對應的方法框架,
#include <jni.h>
若是你熟悉Jni的語法能夠本身去實現,可是太麻煩了,幸虧谷歌爲咱們提供了一個插件gradle-experimental,咱們只須要在app下的gradle.build腳本里配置(僅僅在咱們生成jni方法框架時添加,當咱們所有添加完JNI方法框架以後,必須註釋或者刪除掉,不然run的時候就絕對報錯)
gradle-experimental插件
在2015年5月的Google I/O大會上, Google宣佈Android Studio開始支持NDK開發,經過和JetBrains的合做,將Clion整合進了Android Studio 1.3,並免費支持NDC++開發。同年7月,在Android Studio 1.3版本上添加了 gradle-experimental插件,該插件支持NDK開發和調試,且帶有代碼不全和重構等高級功能。
2.3版本的studio 已經整合了這個插件不用開發者本身手動去添加依賴。(必須配置好ndk開發的環境才能這樣去作,否則會沒反應的)
因此定義好本地方法以後,按alt+enter就會出現下邊的頁面。
點擊左邊的兩個箭頭,點擊就能夠跳轉到本地方法去,也很方便。
六、完成上面5個步驟以後,就能夠make或者run了,而後就會生成對應的so文件(..\build\intermediates\ndk\debug\obj\local)
關注微信公衆號 Android歷練記 或掃一掃二維碼:
讓咱們一塊兒來搞事情。
本文分享自微信公衆號 - 喘口仙氣(gh_db8538619cdd)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。