本站文章均為[?李華明Himi?](http://www.himigame.com/about-himi)原創,轉載務必在明顯處注明:
轉載自[【黑米GameDev街區】](http://www.himigame.com/)?原文鏈接:?[http://www.himigame.com/android-game/725.html](http://www.himigame.com/android-game/725.html "【iOS-cocos2d-X")
[? 點擊訂閱 ?](http://list.qq.com/cgi-bin/qf_invite?id=acfc24e272cc4a26debf3b3866edb626a9ea3fc80fd8893c)?本博客最新動態!及時將最新博文通知您!
很多看過之前Himi的[【iOS-cocos2d-X 游戲開發之七】整合Cocos2dX的Android項目到Xcode項目中,Xcode編寫&編譯代碼,Android導入打包運行即可!](http://www.himigame.com/android-game/667.html)?博文的童鞋都在問我如何在Xcode中能調用Java的函數,比如在Android端需要加入廣告、支付、等第三方平臺或者單獨處理的一些代碼;那么本篇Himi分享如何在Cocos2dx中訪問調用Android的Java層函數;
首先Himi大概的介紹一個類?JniHelper ;
此類主要用于Jni與Java層之間的相互訪問的作用,那么此類的常用的一些函數這里首先介紹下,否則直接上代碼不太容易吸收 ;
JniHelper 類常用函數:
1\. ?getStaticMethodInfo ? ?(四個參數,bool 返回值)
使用示例代碼:
~~~
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中先導入如下頭文件:
~~~
//使用預編譯,對當前平臺為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.無參數,無返回值---------------------------------$$$$$$-----------------------------
#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.無參數,無返回值
public static void testFun() {
Log.e("Himi", "靜態函數示例1.無參數,無返回值");
}
~~~
運行截圖:

示例代碼段2:
Xcode 代碼:
~~~
//靜態函數示例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) 代碼:
~~~
// 靜態函數示例2.有參數,無返回值
public static void testFunWithInt(int _int) {
Log.e("Himi", "靜態函數示例1.有參數,無返回值;傳入的參數int=" + _int);
}
~~~
運行截圖:

示例代碼段3:
Xcode 代碼:
~~~
//靜態函數示例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) 代碼:
~~~
// 靜態函數示例3.有參數,有返回值
public static int testFunWithIntAndRtn(int _int) {
Log.e("Himi", "靜態函數示例1.有參數,有返回值;傳入的參數int=" + _int);
return _int+1000;
}
~~~
運行截圖:

示例代碼段4:
Xcode 代碼:
~~~
#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) 代碼:
~~~
// 靜態函數示例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 代碼:
~~~
#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 代碼:
~~~
//---- 函數示例之非靜態函數調用
//(先獲取個對象)
public static Activity actInstance;//定義單例
public static Object rtnActivity() {
return actInstance;
}
//使用此對象進行調用非靜態函數
public void nostaticFun() {
Log.e("Himi", "no static Function is OK - By Himi");
}
~~~
運行截圖:

- 前言
- 【Iphone 游戲開發】游戲引擎剖析
- [Object-C語言隨筆之一]Mac os 下搭建iOS開發環境
- [Object-C語言隨筆之二] 《NSLog》常用的打印調試語句與自動排版
- [Object-C語言隨筆之三] 類的創建和實例化以及函數的添加和調用!
- [Object-C語言隨筆之四]創建視圖并繪制簡單圖形
- 【iOS-Cocos2d游戲開發之一】搭建cocos2d游戲引擎環境HelloWorld!
- 【iOS-Cocos2d游戲開發之二】Cocos2D 游戲開發資源貼(教程以及源碼)
- 【iOS-Cocos2d游戲開發之三】CCScene切換的所有特效(28種)以及設置屏幕橫豎屏!
- 【iOS-Cocos2d游戲開發之四】獨自收集Cocos2d提供的字體!共57種(有對照的字體圖)
- 【iOS-Cocos2d游戲開發之五】多觸點與觸屏事件詳解(單一監聽、事件分發)【11月28日更新】
- 【iOS-Cocos2d游戲開發之六】對觸屏事件追加講解,解決無法觸發ccTouchMoved事件[重要!]
- 【iOS-Cocos2d游戲開發之七】在cocos2d中添加/刪除系統組件,并解決View設置透明會影響View中的其他組件的問題!【11月28日更新解決添加組件Cocos2d動畫停止播放的BUG】
- 【iOS-Cocos2d游戲開發之八】開啟高清(960*640)模式問題與解答、圖片適配以及設置iphone橫豎屏
- 【iOS-Cocos2d游戲開發之九】講解CCSpriteBatchNode與TP工具的&quot;.pvr.ccz&quot;,&quot;.plist&quot;共用的終極精靈優化及注意事項!
- 【iOS-Cocos2d游戲開發之十】添加粒子系統特效并解決粒子特效與Layer之間的坐標問題;
- 【iOS-Cocos2d游戲開發之十一】使用Box2d物理系統以及在cocos2d框架添加Box2d物理系統lib包的方法
- 【iOS-Cocos2d游戲開發之十二】淺析使用C++/C/OC進行iOS游戲混編出現“failed with exit”問題與小結;
- 【iOS-Cocos2d游戲開發之十三】CCSprite利用Bezier(貝塞爾)做拋物線動作并讓CCSprite同時播放兩個Action動作!
- 【iOS-Cocos2d游戲開發之十四】音頻/音效/視頻播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d進行視頻播放!)
- 【iOS-Cocos2d游戲開發之十五】詳解CCProgressTimer 進度條并修改cocos2d源碼實現“理想”游戲進度條!
- 【iOS-Cocos2d游戲開發之十六】添加本地通知(UILocalNotification)以及添加系統組件滾動視圖(UIScrollView)!【2011年11月15日更新】
- 【iOS-Cocos2d游戲開發之十七】靈活使用精靈可視區域(TextureRect)與錨點(anchorPoint),并結合可視區域與錨點制作進度條!
- 【iOS開發必備指南合集】申請企業級IDP、真機調試、游戲接入GameCenter 指南(實現仿官方的成就提示)、游戲接入OpenFeint指南;
- 【iOS-Cocos2d游戲開發之十八】解決滾屏背景/拼接地圖有黑邊(縫隙)/動畫播放出現毛邊以及禁止游戲中自動鎖屏問題!【2011年12月18日補充】
- 【iOS開發必收藏】詳解iOS應用程序內使用IAP/StoreKit付費、沙盒(SandBox)測試、創建測試賬號流程!【2012-12-11日更新獲取&quot;產品付費數量等于0的問題&quot;】
- 【iOS-cocos2d-X 游戲開發之一】在Mac下結合Xcode搭建Cocos2d-X開發環境!
- 【iOS-cocos2d-X 游戲開發之二】【必看篇】總結闡述Cocos2d-X與Cocos2d-iphone區別;
- 【iOS-Cocos2d游戲開發之十九】游戲數據存儲的四種常用方式NSKeyedArchiver/NSUserDefaults/Write寫入/SQLite3
- 【iOS-Cocos2d游戲開發之二十】精靈的基礎知識點總匯(位圖操作/貼圖更換/重排z軸等)以及利用CCSprite與CCLayerColor制作簡單遮蓋層!
- 【iOS-Cocos2d游戲開發之二十一 】自定義精靈類并為你的精靈設置攻擊幀(指定開始幀)以及擴展Cocos2d源碼的CCAnimation簡化動畫創建!
- 【iOS-Cocos2d游戲開發之二十二 】CCSpeed實現CCAnimate動畫進行時設置慢動作以及設置游戲加減速進行(塔防游戲必備)!
- 【iOS-cocos2d-X 游戲開發之三】Mac下配置Android NDK環境并搭建Cocos2d-x環境并Eclipse正常編譯運行Cocos2dX自帶TestsDemo項目!
- 【iOS-cocos2d-X 游戲開發之四】Cocos2dX創建Android NDK新項目并編譯導入Eclipse中正常運行!
- 【iOS-cocos2d-X 游戲開發之五】游戲存儲之Cocos2dX自帶CCUserDefault類詳解;
- 【iOS-cocos2d-X 游戲開發之六】使用Base64算法對Cocos2dX自帶CCUserDefault游戲存儲數據編碼!
- 【iOS-cocos2d-X 游戲開發之七】整合Cocos2dX的Android項目到Xcode項目中,Xcode編寫&amp;編譯代碼,Android導入打包運行即可!
- 【iOS-iap防護】驗證用戶付費收據!拒絕iap Cracker!拒絕iap Free!讓iphone越獄用戶無從下手!【2012年5月2日更新防護iap Free的方法】
- 【COCOS2DX-LUA 腳本開發之一】在Cocos2dX游戲中使用Lua腳本進行游戲開發(基礎篇)并介紹腳本在游戲中詳細用途!
- 【iOS-cocos2d-X 游戲開發之九】Cocos2dx利用CCSAXParser解析xml數據&amp;CCMutableDictionary使用與注意!
- 【iOS-cocos2d-X 游戲開發之十】自定義CCSprite/Layer/CCNode及靜態類模版&amp;自定義類細節說明&amp;Cocos2dx觸屏事件講解
- 【iOS-cocos2d-X 游戲開發之十一】New CCSprite()帶來的錯誤&amp;使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!
- 【iOS-cocos2d-X 游戲開發之十二】自定義Cocos2dx搖桿(增強Joystick),增加搖桿跟隨用戶觸點作為搖桿坐標,讓搖桿不再死板!
- 【iOS-cocos2d-X 游戲開發之十三】詳細講解在Xcode中利用預編譯并通過Jni調用Android的Java層代碼(cocos2dx里訪問調用Android函數)!
- 【iOS-cocos2d-X 游戲開發之十四】Xcode中c++&amp;Object-C混編,詳細介紹如何在cocos2dx中訪問object函數以及Apple Api
- 【iOS-cocos2d-X 游戲開發之十五】Cocos2dx中響應Android的Back(返回)與Menu(小房子)事件&amp;&amp;Cocos2dx自動釋放粒子內存函數!
- 【iOS-cocos2d-X 游戲開發之十六】配置你的Cocos2dx項目編譯后的Android自動使用(-hd)高清圖&amp;設置Android自適應屏幕、縮放比例方法!
- 【Cocoa(mac) Application 開發系列之四】動作編輯器(Cocos2dx)制作流程詳解及附上響應鼠標滾軸事件、反轉坐標系、導入/創建資源目錄等知識點代碼!
- 【Cocos2d-X(2.x) 游戲開發系列之一】cocos2dx(v2.x)與(v1.x)的一些常用函數區別講解!在2.x版CCFileData類被去除等
- 【Cocos2d-X(2.x) 游戲開發系列之二】cocos2dx最新2.0.1版本跨平臺整合NDK+Xcode,Xcode編寫&amp;編譯代碼,Android導入打包運行即可!
- 【Cocos2dX(2.x)_Lua開發之三】★重要必看篇★在Lua中使用自定義精靈(Lua腳本與自創建類之間的訪問)及Lua基礎講解
- 【Cocos2d-X(2.x) 游戲開發系列之三】最新版本cocos2d&#173;2.0&#173;x&#173;2.0.2使用新資源加載策略!不再沿用-hd、-ipad、-ipadhd添加后綴方式
- 【Cocos2d-X(1.x 2.x) 修復篇】iOS6 中 libcurl.a 無法通過armv7s編譯以及iOS6中無法正常游戲橫屏的解決方法
- 【Cocos2d-X(1.x 2.x) 】iOS6與iphone5適相關設置隨筆(解決第三方類庫無法通過armv7s編譯的方法、添加Default-568h@2x.png)