原文地址::http://blog.csdn.net/loseleo/article/details/5858862
首先,這裡所要講的主要是C調用java的,因為這裡網上也沒有一個詳細的資料,其次,我開發android應用沒多久,其中java錯誤敬請諒解!
關於配置NDK環境問題應該不用再贅述了,這個網上有很多,只要配置好能編譯JNI的本地樣本程式就可以了。
(NDK-1.6版本)
一、 這裡講一下如何自己寫JNI程式,網上很多都是講用javah自動產生,其實並沒有太多必要。首先進入android-ndk-1.6_r1/apps 複製hello-jni檔案夾到app目錄下,更改名字為你想要的,這裡就叫 test-jni,然後進入test-jni目錄 ,用寫字板開啟Application.mk
內容改為
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := test-jni
儲存關閉。再進入project/jni目錄開啟 Android.mk
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
這兩個更改為
LOCAL_MODULE := test-jni
LOCAL_SRC_FILES := test-jni.c
同時把hello-jni.c改為test-jni.c 這樣,你可以使用make APP=test-jni -B命令去編譯你的jni了。
二、這裡講一下如何手動寫jni代碼
接著上面建立出來的jni,編譯時間可以通過,但無法使用,因為jni函數有一個函數名規範。開啟test-jni.c 會看的
Java_com_example_hellojni_HelloJni_stringFromJNI 這個命名是有詳細規範的,Java_ 開頭 下面是你在java哪個類裡面要使用,比如我要在com/example/hellojni下面的testjni類中使用,那就要命名為Java_com_example_hellojni_testjni_stringFromJNI。
然後是參數JNIEnv* env,jobject thiz ,這兩個是預設的參數,第一個是java虛擬機器,必須有,第二個可以不用,相當於當前類的對象的指標,也就是this。
裡面內容的寫法也有很多,無非是 一些標準C的處理了。這裡要注意的是java那邊的 數群組類型在這邊對應的都是一個類的指標,比如byte[],在c這邊是JbyteArray,
要擷取數組的值要用
int len =(*env)->GetArrayLength(env,msg);
jbyte* elems =(*env)-> GetByteArrayElements(env,msg, 0);
(*env)->ReleaseByteArrayElements(env,msg, elems, 0);
三、重點:C調用java。
先講一下我理解的調用過程,c要先找到這個類,然後要有一個對象,然後在這個類的對象基礎上調用這個函數。
因此調用java函數首先要有類,然後函數ID,然後對象
cls = (*env)->FindClass(env,"com/example/hellojni/Ext_Graphics");
//擷取數組
mid = (*env)->GetMethodID(env,cls,"getCanvasBmpByte","()[B"); //這裡的最後一個參數是用javap -s -p 命令拿到的,很多文章有講過
msg = (jbyteArray)(*env)->CallObjectMethod(env,job, mid); //注意這裡的第二個參數就是對象,意義就是你調用的是當前類的當前對象的這個方法,如果當前類沒有這個函數那就直接出錯了,如果你要在其他類裡面調用這個方法,請把這個類的對象的引用做參數傳遞進來:
Java_com_example_hellojni_HelloJni_InitGraphics( JNIEnv* env,jobject thiz ,jobject job )//這個就是函數所在的對象
暫時就只有這些,具體不清楚請回我訊息吧~我會解答的
首先,這裡所要講的主要是C調用java的,因為這裡網上也沒有一個詳細的資料,其次,我開發android應用沒多久,其中java錯誤敬請諒解!
關於配置NDK環境問題應該不用再贅述了,這個網上有很多,只要配置好能編譯JNI的本地樣本程式就可以了。
(NDK-1.6版本)
一、 這裡講一下如何自己寫JNI程式,網上很多都是講用javah自動產生,其實並沒有太多必要。首先進入android-ndk-1.6_r1/apps 複製hello-jni檔案夾到app目錄下,更改名字為你想要的,這裡就叫 test-jni,然後進入test-jni目錄 ,用寫字板開啟Application.mk
內容改為
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := test-jni
儲存關閉。再進入project/jni目錄開啟 Android.mk
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
這兩個更改為
LOCAL_MODULE := test-jni
LOCAL_SRC_FILES := test-jni.c
同時把hello-jni.c改為test-jni.c 這樣,你可以使用make APP=test-jni -B命令去編譯你的jni了。
二、這裡講一下如何手動寫jni代碼
接著上面建立出來的jni,編譯時間可以通過,但無法使用,因為jni函數有一個函數名規範。開啟test-jni.c 會看的
Java_com_example_hellojni_HelloJni_stringFromJNI 這個命名是有詳細規範的,Java_ 開頭 下面是你在java哪個類裡面要使用,比如我要在com/example/hellojni下面的testjni類中使用,那就要命名為Java_com_example_hellojni_testjni_stringFromJNI。
然後是參數JNIEnv* env,jobject thiz ,這兩個是預設的參數,第一個是java虛擬機器,必須有,第二個可以不用,相當於當前類的對象的指標,也就是this。
裡面內容的寫法也有很多,無非是 一些標準C的處理了。這裡要注意的是java那邊的 數群組類型在這邊對應的都是一個類的指標,比如byte[],在c這邊是JbyteArray,
要擷取數組的值要用
int len =(*env)->GetArrayLength(env,msg);
jbyte* elems =(*env)-> GetByteArrayElements(env,msg, 0);
(*env)->ReleaseByteArrayElements(env,msg, elems, 0);
三、重點:C調用java。
先講一下我理解的調用過程,c要先找到這個類,然後要有一個對象,然後在這個類的對象基礎上調用這個函數。
因此調用java函數首先要有類,然後函數ID,然後對象
cls = (*env)->FindClass(env,"com/example/hellojni/Ext_Graphics");
//擷取數組
mid = (*env)->GetMethodID(env,cls,"getCanvasBmpByte","()[B"); //這裡的最後一個參數是用javap -s -p 命令拿到的,很多文章有講過
msg = (jbyteArray)(*env)->CallObjectMethod(env,job, mid); //注意這裡的第二個參數就是對象,意義就是你調用的是當前類的當前對象的這個方法,如果當前類沒有這個函數那就直接出錯了,如果你要在其他類裡面調用這個方法,請把這個類的對象的引用做參數傳遞進來:
Java_com_example_hellojni_HelloJni_InitGraphics( JNIEnv* env,jobject thiz ,jobject job )//這個就是函數所在的對象
暫時就只有這些,具體不清楚請回我訊息吧~我會解答的