一、什麼是JNI?
Java Native Interface java本地接口
提供了java與其他語言的通信接口,主要是Android中的c和c++,方便調用底層的一些功能強大的方法
一句話總結就是,java代碼調用c和c++代碼。
二、爲什麼使用JNI?
1.效率
java代碼跨平臺,虛擬機解釋執行,不能執行操作硬件,雖然現在有了art模式,但是art模式安裝應
用體積會變大
C代碼直接操作硬件,效率高,而且我們可以自己手動釋放內存
2.優秀C和C++代碼
c和c++發展已經有好幾十年,已經有了很多優秀的框架,比如ffmpeg-多媒體播放器;opencv-圖形識
別;7-zip壓縮,這些都已經成形,可以直接用,不必要用java重新造輪子
3.應用場景
智能家居,車載電腦等等都需要我們來直接操作硬件
4.特殊業務邏輯
c和c++反編譯困難,調試困難,java代碼反編譯簡單,容易看懂;爲了提高代碼的安全性,可以用c
和c++來開發一些比較重要的業務邏輯
三、開發流程
一般用ndk開發工具,工具可以在網上下載,工具使用可以參考ndk中docs文檔,非常詳盡
流程:
1.java中聲明native方法
public native String helloFromC();
2.as中main目錄下創建jni目錄
3.編寫c代碼,jni目錄下創建.c文件,
jstring Java_com_itheima_hellojni_MainActivity_helloFromC(JNIEnv* env,jobject obj){
char* str = "hello from c !!";
//在jni規範裏面 在jni環境的結構體裏面
//jstring (*NewStringUTF)(JNIEnv*, const char*);
//轉化成了java的字符串
return (*(*env)).NewStringUTF(env,str);
}
//Java_包名_類型_方法名(jvm虛擬機的指針,調用者對象)
4.配置Android.mk文件,添加jni.h文件(ndk目錄中有,選擇適合自己的)
#指定編譯的文件夾 指定當前文件目錄
LOCAL_PATH := $(call my-dir)
#編譯器會定義很多的臨時變量,中間變量,最好清空所有的中間變量。
include $(CLEAR_VARS)
#編譯出來模塊的名稱
LOCAL_MODULE := hello
# 編譯的源代碼的名稱
LOCAL_SRC_FILES := hello.c
#編譯一個動態庫,靜態庫
#靜態庫 文件名.a 包含所有的函數並且函數運行的依賴,體積大,包含所有的API
#動態庫 文件名.so 包含函數,不包含函數運行的依賴,體積小,運行的時候,去操作系統尋找需要的API
include $(BUILD_SHARED_LIBRARY)
5.執行ndk-build.cmd編譯c代碼,生成動態庫.so
6.在java中把動態鏈接庫加到jvm虛擬機
static{
System.loadLibrary("庫文件名稱不帶前綴,後綴名");
}
庫文件名就是步驟4中的LOCAL_MODULE對應的名稱
7.像調用java一樣調用native方法
小結:一步一個腳印,慢慢學習