本站文章均爲 李華明Himi 原創,轉載務必在明顯處註明:(作者新浪微博: @李華明Himi )
轉載自【黑米GameDev街區】 原文鏈接: http://www.himigame.com/android-game/725.html
很多看過之前Himi的【iOS-cocos2d-X 遊戲開發之七】整合Cocos2dX的Android項目到Xcode項目中,Xcode編寫&編譯代碼,Android導入打包運行即可! 博文的童鞋都在問我如何在Xcode中能調用Java的函數,比如在Android端需要加入廣告、支付、等第三方平臺或者單獨處理的一些代碼;那麼本篇Himi分享如何在Cocos2dx中訪問調用Android的Java層函數;
首先Himi大概的介紹一個類 JniHelper ;
此類主要用於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" ); } |
運行截圖: