什麼是jni
jni的全稱是:java native interface, java本地接口
其實我們也可以將 JNI理解爲一個協議 ,這個協議用來溝通java代碼和外部的本地代碼(c/c++)的,通過這個協議,java代碼就可以調用外部的c/c++代碼, 外部的c/c++代碼也可以調用java代碼,他就相當於是一個橋樑。
jni的開發流程
1、在java代碼中聲明一個native本地方法public native String test();
2、在項目目錄裏邊創建一個jni文件夾
3、在jni文件夾裏面創建c文件,然後 按照規範寫代碼,這個規範可以參考ndk目錄下的jni.h
比如上邊我們需要返回一個字符串,則規範代碼爲:
#include *jni.h //規範文件
代碼解釋:
Java_com_deeny_jniDemo_MainActivity_test:大寫Jave開頭,下劃線,完整的包名,下劃線,方法名
env:jni接口的指針的指針
jobject:誰調用的這個方法,就是誰,比如當前是MainActivity調用的,那麼當前的obj就是MainActivity的對象
jstring Java_com_deeny_jniDemo_MainActivity_test(JNIEnv* env,jobject obj){
char* str=“test!!!”;
//*env 是JNIEnv這個指針,需要拿到他裏邊的一個結構體對象,所以需要將其前邊再加上一個*,具體可以參考jni.h
return (*(*env)).NewStringUTF(env,str);
}
4、ndk-builder 指令編譯
編譯前需要配置Android.mk文件
//制定編譯的文件夾,指定當前目錄
LOCAL_PATH := $(call my-dir)
//編譯器在編譯的時候會生成很多臨時變量,中間變量,最好是便宜之前先清空所有的臨時變量
include $(CLEAR_VARS)
//編譯完成的模塊名
LOCAL_MODULE := test
//編譯的源文件
LOCAL_SRC_FILES := test.c
//編譯一個動態庫
//動態庫:文件名.so 只包含運行的函數,不包含依賴,體積小,運行的時候會去系統尋找依賴
//靜態庫:文件名.a 包含所有的函數和函數運行的依賴,體積大,包含所有的api
include $(BUILD_SHARED_LIBRARY)
5、生成一個so動態庫 放到libs裏邊
6、引入依賴庫,通過靜態代碼塊的形式引入
7、調用本地方法,和java調用普通方法一致
使用jni的優缺點
優點:提高了程序的性能,能夠使java和其他語言進行交互
缺點:破壞了java的可移植性,也給java的安全帶來了隱患