cocos2dx用jni調用Android函數

此類主要用於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值表示是否找到此函數
    boolisHave = 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值表示是否找到此函數
    boolisHave = 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);
}

運行截圖:

 
示例代碼段3:

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;
    boolisHave = 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;
}

運行截圖:

 
示例代碼段4:

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值表示是否找到此函數
    boolisHave = 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";
}

運行截圖:

示例代碼段5:

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值表示是否找到此函數
    boolisHave = 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() {
    returnactInstance;
}
//使用此對象進行調用非靜態函數
public void nostaticFun() {
    Log.e("Himi","no static Function is OK - By Himi");
}

運行截圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章