先來一張截圖
項目結(jié)構(gòu)
1.TestJni類中聲明native的方法勿璃,并且需要靜態(tài)引入我們通過ndk交叉編譯后的lib(Android中也就是 .so文件)
TestJni.java
- 可以看到我這邊寫了兩個native方法晶乔,用來區(qū)分靜態(tài)注冊募强、動態(tài)注冊native方法
- static靜態(tài)代碼塊可以看到和項目的jni目錄下生成的so包名字不一樣振定,這里需要省略lib前綴和.so后綴
2.com_csh_test_TestJni.h 這個是頭文件,可以自己按照規(guī)范寫 脐供,當然不需要自己寫拓颓,可以通過javah命令生成,首先需要將TestJni這個類javac編譯成字節(jié)碼关筒,然后對這個class文件用javah生成.h文件
com_csh_test_TestJni.h
3.首先看看test.c(注意是c不是c++溶握,c++有些區(qū)別)
test.c
當然有點c語言基礎(chǔ)的都知道,本人c語言比較爛蒸播,多多指教啊
- 首先引入頭文件
- 靜態(tài)注冊native方法直接實現(xiàn)就好睡榆,按照jni的java與c之間的轉(zhuǎn)換規(guī)則
- 動態(tài)注冊這里只說說怎么做,JNINativeMethod數(shù)組可以有多個方法映射袍榆,第一第三個參數(shù)是映射java中聲明的native方法dynamicRegFromJni對應(yīng)到c中自己定義的方法nativeDynamicRegFromJni胀屿,第二個參數(shù)()Ljava/lang/String; 其中()是指native方法參數(shù)為空,Ljava/lang/String;是指返回值為string (方法描述蜡塌,數(shù)據(jù)類型描述 參考)
- JNI_OnLoad(JavaVM *jvm, void *reserved)這個方法是load so文件的時候會被調(diào)用碉纳,我們就在這個方法中實現(xiàn)動態(tài)注冊
4.Android.mk文件這里我是手動寫的,也可以gradle中配置自動生成(參考)
Android.mk
最后說一句
實踐了c++寫法略有不同
test.cpp
可以看到區(qū)別在指針與引用的區(qū)別
查看jni.h中JNIEnv的定義:
#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
#else
typedef const struct JNINativeInterface* JNIEnv;
#endif
發(fā)現(xiàn)C和C++對于JNIEnv定義不同馏艾,簡單點說劳曹,c++是支持類可以直接通過類引用調(diào)用方法,c則取出函數(shù)指針所引用的值去調(diào)用相應(yīng)的方法