AndroidStudio3.0中JNI開發
阿新 • • 發佈:2018-11-14
1.什麼是JNI?
JNI 是java native interface 的縮寫,如果想實現JAVA呼叫C、C++ ,那麼就需要利用JNI來實現,JNI可以使java和c、c++ 相互呼叫, JNI可以看做是翻譯,其實就是一套協議。
2.為什麼要用JNI?
驅動程式一般都是用C寫的,如果JAVA想操作硬體那麼就需要去跟C去互動,如果想利用android 軟體來控制硬體,比如在手機中點選一個按鈕就可以控制電燈的開啟和關閉,比如點選手機中的按鈕就可以控制小區門禁的開啟和關閉 ,比如如果想實現人臉識別的功能,就可以利用java來呼叫jni,然後通過jni來呼叫OpenCV實現人臉識別的功能.
3.怎麼使用JNI?
要用JNI,首先要學c、c++的基礎
NDK 是native develop kit的縮寫, DNK是谷歌在Androud下給開發JNI的一套工具
3.0 給當前的專案新增NDK支援
3.1、宣告一個本地函式:
/**
* JNI開發的步驟
* 1、宣告本地方法,使用native關鍵字,該本地方法不用實現
* @return
*/
public native String helloFromC();
3.2、在專案的main資料夾下建立jni檔案下,比建立一個.c檔案
3.3、建立一個本地函式,比實現該函式
/* 建立本地函式 在C中用jstring來表示JAVA中的String C本地函式的命名規則為: Java_呼叫C本地函式的的使用者包名_使用者類名_呼叫本地函式的函式名(JNIEnv* env,jobject thiz) Java_com_casic_jni_MainActivity_helloFromC(JNIEnv* env,jobiect thiz) JNIEnv* env 是一個指標, 它是結構體JNINativeInterface 的二級指標 JNIEna 是結構體JNINativeInterface的一級指標 實現將 JNIEnv* env轉換成JNINativeInterface的一級指標: (*env) ->是C中的間接運算子 jobiect 即相當於JAVA中的object ,它是呼叫本地函式的java物件,當前的thiz就是MainActivity這個物件 (JNIEnv* env,jobiect thiz) 這兩個引數是固定的,就算呼叫C的本地函式時不用傳遞任何引數,那麼這兩個引數也是必須要有有的。如果需要傳遞引數,那麼在後面新增即可 */ jstring Java_com_casic_jnitestthree_MainActivity_helloFromC(JNIEnv* env,jobject thiz){ /* 實現當呼叫本地函式時返回一個字串回去 */ char* str = "hello from c!"; //通過jni.h中的NewStringUTF(env,cstr) 函式實現將char*資料型別轉換為jstring資料型別 return (*env)->NewStringUTF(env,str); }
3.4、在jni目錄下建立一個Android.mk檔案,並在其中加入如下程式碼:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_SHARED_LIBRARY)
3.5、進入到該專案的根目錄下,通過ndk-nuild命令對其c檔案進行編譯,如果編譯成功就會在生成如下檔案
3.6、在main目錄下建立一個jniLibs的檔案下,並將libs檔案下的所有檔案都拷貝到該目錄中
3.7、載入so檔案
System.loadLibrary("hello");
3.8、呼叫最開始宣告的本地函式
/*
* 6、呼叫本地函式
* */
String s = helloFromC();
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
3.9、在gradle.properties檔案中的預設新增如下程式碼:
Android.useDeprecatedNdk=true
3.10、在app的build.gradle檔案中新增如下程式碼:
ndk{
moduleName "hello"
}
sourceSets.main{
jniLibs.srcDirs = ['src/main/jniLibs'];
}
sourceSets {
main {
jni.srcDirs = []
}
}
效果圖: