此類主要用於Jni與Java層之間的相互訪問的作用,那麼此類的常用的一些函數這裏首先介紹下,否則直接上代碼不太容易吸收 ;
JniHelper 類常用函數:
1. getStaticMethodInfo (四個參數,bool 返回值)
使用示例代碼:
1
|
bool
isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFun" , "()V" ); |
此函數主要用於獲取Java定義的類靜態函數是否存在,返回bool;
此函數有3個參數:
第一參數: minfo ->JniMethodInfo 類型,後面詳細說;
第二個參數:類的路徑。
第三個參數:方法名(第一參數類中的函數)
第四個參數:(參數)返回類型
關於第一個和第二個參數都比較容易理解,那麼第三個參數需要重點介紹一下;例如你在Java中定義一個如下函數 public void helloJni(){};
那麼getStaticMethodInfo函數第三個參數你應該傳入 “()V” 表示此函數無參無返回值!
如果有這麼一個函數: public int helloJni(int _int){return 823};
那麼getStaticMethodInfo函數第三個參數你應該傳入 “(I)I” 表示此函數需要傳入一個int類型的參數並且返回一個int類型!
大概說兩個童鞋們應該基本理解了,那麼下面詳細寫一些對照表,留給大家對照;
參數、返回值樣式對照表:
這裏的簽名指的就是getStaticMethodInfo函數第三個參數中傳入的樣式;
2. getMethodInfo 類似與第一個函數,只是對應非靜態函數;此函數主要用於獲取Java定義的類非靜態函數是否存在,返回bool;
JniMethodInfo 類:
此類型主要用戶保存類結構體,可以通過JniHelper類的getStaticMethodInfo函數實例化JniMethodInfo對象,從而使用實例的env屬性調用CallStaticVoidMethod,CallVoidMethod,CallStaticIntMethod等函數進行對保存的類結構調用函數;
常用的函數如下:(靜態系列函數)
1. CallStaticVoidMethod(classID,methodID);
2. CallStaticIntMethod(classID,methodID);
3~(n-1) ……省略掉,童鞋們一看就明白;
n. CallStaticObjectMethod(classID,methodID);
帶參數的函數:(如int類型)
CallStaticVoidMethod(classID,methodID,int _int);
非靜態系列函數:
1. CallVoidMethod(jobj,methodID);
2. CallIntMethod(jobj,methodID);
3~(n-1) ……省略掉,童鞋們一看就明白;
n. CallStaticObjectMethod(jobj,methodID);
帶參數的函數:(如int類型)
CallVoidMethod(classID,methodID,int _int);
這裏講解下幾個參數函數:
1. classID: 類ID , JniMethodInfo 對象包含此屬性;
2. methdID: 方法ID,JniMethodInfo 對象也包含此屬性;
3. jobj : java中Object類型,如自定義類,String…
非靜態函數調用的時候,需要的是對象,所以與靜態函數調用的第一個參數不同;
那麼既然能調用Java的函數,那就能得到函數返回值,但是這裏我們得到的返回值書寫類型如下:
譬如返回int 類型,在Xcode中使用 jint 這種形式,更多形式如下:
int -> jint
…省略,大家一看就懂得;
object -> jobject
估計有的童鞋已經暈了,沒關係,下面Himi寫了一些例子代碼,結合來看就一目瞭然啦。
Xcode中先導入如下頭文件:
1
2
3
4
5
6
7
|
//使用預編譯,對當前平臺爲Android時纔會導入如下頭文件 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include <jni.h> #include "platform/android/jni/JniHelper.h" #include <android/log.h> #endif |
示例代碼段1:
Xcode 代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
////靜態函數示例1.無參數,無返回值---------------------------------$$$$$$----------------------------- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判斷當前是否爲Android平臺 JniMethodInfo minfo; //定義Jni函數信息結構體 //getStaticMethodInfo 次函數返回一個bool值表示是否找到此函數 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFun" , "()V" ); if (!isHave) { CCLog( "jni:此函數不存在" ); } else { CCLog( "jni:此函數存在" ); //調用此函數 minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID); } CCLog( "jni-java函數執行完畢" ); #endif |
Android(Java) 代碼:
1
2
3
4
|
// 靜態函數示例1.無參數,無返回值 public
static void testFun() { Log.e( "Himi" , "靜態函數示例1.無參數,無返回值" ); } |
運行截圖:
示例代碼段2:
Xcode 代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//靜態函數示例2.有參數,無返回值------------------------------$$$$$$$-------------------------------- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判斷當前是否爲Android平臺 JniMethodInfo minfo; //定義Jni函數信息結構體 //getStaticMethodInfo 次函數返回一個bool值表示是否找到此函數 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithInt" , "(I)V" ); if (!isHave) { CCLog( "jni:此函數不存在" ); } else { CCLog( "jni:此函數存在" ); //調用此函數 minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,823); } CCLog( "jni-java函數執行完畢" ); #endif |
Android(Java) 代碼:
1
2
3
4
|
// 靜態函數示例2.有參數,無返回值 public
static void testFunWithInt( int _int) { Log.e( "Himi" , "靜態函數示例1.有參數,無返回值;傳入的參數int=" +
_int); } |
運行截圖:
Xcode 代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
//靜態函數示例3.有參數,有返回值--------------------------------$$$$$$$-------------------------------- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判斷當前是否爲Android平臺 JniMethodInfo minfo; //定義Jni函數信息結構體 //getStaticMethodInfo 次函數返回一個bool值表示是否找到此函數 bool
isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithIntAndRtn" , "(I)I" ); jint _int ; if
(!isHave) { CCLog( "jni:此函數不存在" ); } else { CCLog( "jni:此函數存在" ); //調用此函數 _int = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID,823); //嘗試jint是否能正常接收返回的int值 JniMethodInfo minfo_ty; bool isHave = JniHelper::getStaticMethodInfo(minfo_ty, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithInt" , "(I)V" ); if (isHave) { minfo_ty.env->CallStaticVoidMethod(minfo_ty.classID, minfo_ty.methodID,_int); } } CCLog( "jni-java函數執行完畢" ); #endif |
Android(Java) 代碼:
1
2
3
4
5
|
// 靜態函數示例3.有參數,有返回值 public
static int testFunWithIntAndRtn( int _int) { Log.e( "Himi" , "靜態函數示例1.有參數,有返回值;傳入的參數int=" +
_int); return _int+ 1000 ; } |
運行截圖:
Xcode 代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判斷當前是否爲Android平臺 JniMethodInfo minfo; //定義Jni函數信息結構體 //getStaticMethodInfo 次函數返回一個bool值表示是否找到此函數 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithStringAndRtn" , "(I)Ljava/lang/String;" ); jobject jobj; if (!isHave) { CCLog( "jni:此函數不存在" ); } else { CCLog( "jni:此函數存在" ); //調用此函數 jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID,823); } CCLog( "jni-java函數執行完畢" ); #endif |
Android(Java) 代碼:
1
2
3
4
5
|
// 靜態函數示例4.有參數,有返回值(String類型) public
static String testFunWithStringAndRtn( int _int) { Log.e( "Himi" , "靜態函數示例4.有參數,有返回值(String類型);int=" +
_int); return "yes,return 'String' is OK --by Himi" ; } |
運行截圖:
Xcode 代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判斷當前是否爲Android平臺 JniMethodInfo minfo; //定義Jni函數信息結構體 //getStaticMethodInfo 次函數返回一個bool值表示是否找到此函數 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , //類的路徑 "rtnActivity" , //方法名 "()Ljava/lang/Object;" ); //括號裏的是參數,後面的是返回值。 jobject jobj; if (isHave) { jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); } CCLog( "正確獲取到 jobj" ); // isHave = JniHelper::getMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , //類的路徑 "nostaticFun" , //方法名 "()V" ); //括號裏的是參數,後面的是返回值。 if (isHave) { minfo.env->CallVoidMethod(jobj, minfo.methodID); } CCLog( "jni-java函數執行完畢" ); #endif |
Java 代碼:
1
2
3
4
5
6
7
8
9
10
|
//---- 函數示例之非靜態函數調用 //(先獲取個對象) public
static Activity actInstance; //定義單例 public
static Object rtnActivity() { return actInstance; } //使用此對象進行調用非靜態函數 public
void nostaticFun() { Log.e( "Himi" , "no static Function is OK - By Himi" ); } |
運行截圖: