- cocos2d-x 通过JNI实现c/c++和Android的java层函数交互
-
1.JNI
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
JNI实现流程:

2.C++与java交互流程图:

注:对于跨平台的 cocos2d-x 来说,除非必要,否则可不必深究其理,比如想要使用 Android 平台固有的特性等,那就需要更多的了解 Jni 使用方法,以及 Android 操作系统的更多细节。
3.实例:
实现功能:
(1)通过Android sdk的API得到应用程序的包名(PackageName),然后传递给c++层函数。
(2)通过c++函数调用Android的java层函数,显示一个对话框,点击按钮退出程序。
4.实现步骤:
4.1 使用cocos2d-x创建工程DialogBox及搭配android环境
android环境,如图:

4.2 c++部分
先到win32环境,编写提供android调用c++接口:
JniTest.h
1234567891011121314151617#ifndef JNI_TEST_H#define JNI_TEST_H#include"cocos2d.h"using namespace cocos2d;voidsetPackageName(constchar*packageName){CCLog("packageName: %s", packageName);}voidexitApp(){CCDirector::sharedDirector()->end();}#endif
调用android API接口:
HelloWorldScene.cpp
12345678910111213141516#include"HelloWorldScene.h"#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)#include"../proj.android/jni/hellocpp/test.h"#endifUSING_NS_CC;voidHelloWorld::menuCloseCallback(CCObject* pSender){#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)showTipDialog("exit","alexzhou,really go?");#endif#if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)exit(0);#endif}
注:只需要更改下HelloWorldScene就OK了。
接着转到android平台,编写jni层代码:
test.h
test.cpp12345678#ifndef TEST_H#define TEST_Hextern"C"{voidshowTipDialog(constchar*title,constchar*msg);}#endif
1234567891011121314151617181920212223242526272829303132333435363738#include"cocos2d.h"#include <JNI.H>#include"platform/android/jni/JniHelper.h"#include"test.h"#include"JniTest.h"#define CLASS_NAME"com/DialogBox/org/JniTestHelper"using namespace cocos2d;extern"C"{voidshowTipDialog(constchar*title,constchar*msg){JniMethodInfo t;if(JniHelper::getStaticMethodInfo(t, CLASS_NAME,"showTipDialog","(Ljava/lang/String;Ljava/lang/String;)V")){jstring jTitle = t.env->NewStringUTF(title);jstring jMsg = t.env->NewStringUTF(msg);t.env->CallStaticVoidMethod(t.classID, t.methodID, jTitle, jMsg);t.env->DeleteLocalRef(jTitle);t.env->DeleteLocalRef(jMsg);}}voidJava_com_DialogBox_org_JniTestHelper_setPackageName(JNIEnv *env, jobject thiz, jstring packageName){constchar*pkgName = env->GetStringUTFChars(packageName, NULL);setPackageName(pkgName);env->ReleaseStringUTFChars(packageName, pkgName);}voidJava_com_DialogBox_org_JniTestHelper_exitApp(JNIEnv *env, jobject thiz){exitApp();}}注:这里必须加上extern “C”,声明以c语言的方式进行编译,因为c++和c在编译时生成的函数签名不一样,可以在网上查找相关资料,不然运行的时候会出现链接错误。
4.3 Java部分:
c++函数调用java层函数,显示一个对话框:
JniTestHelper.java
创建一个DialogMessage.java,封装dialog要显示的数据:12345678910111213141516171819202122232425262728packagecom.DialogBox.org;importorg.cocos2dx.lib.Cocos2dxHandler.DialogMessage;importandroid.os.Handler;importandroid.os.Message;publicclassJniTestHelper {privatestaticHandler mHandler;publicstaticvoidinit(Handler handler){JniTestHelper.mHandler = handler;}publicstaticnativevoidsetPackageName(String packageName);publicstaticnativevoidexitApp();//c++函数调用java层函数,显示一个对话框privatestaticvoidshowTipDialog(finalString title,finalString text){Message msg = mHandler.obtainMessage();msg.what = DialogBox.SHOW_DIALOG;DialogMessage dm =newDialogMessage(title, text);msg.obj = dm;msg.sendToTarget();}}
修改主程序DialogBox.java123456packagecom.DialogBox.org;publicclassDialogMessage {publicString title;publicString msg;}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455publicclassDialogBoxextendsCocos2dxActivity{publicstaticfinalintSHOW_DIALOG =0x0001;protectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);JniTestHelper.init(mHandler);JniTestHelper.setPackageName(this.getPackageName());}publicCocos2dxGLSurfaceView onCreateView() {Cocos2dxGLSurfaceView glSurfaceView =newCocos2dxGLSurfaceView(this);// GuideLayer should create stencil bufferglSurfaceView.setEGLConfigChooser(5,6,5,0,16,8);returnglSurfaceView;}static{System.loadLibrary("cocos2dcpp");}//显示对话框的函数privateHandler mHandler =newHandler(){@OverridepublicvoidhandleMessage(Message msg) {switch(msg.what){caseSHOW_DIALOG:DialogMessage dm = (DialogMessage)msg.obj;newAlertDialog.Builder(DialogBox.this).setTitle(dm.titile).setMessage(dm.message).setNegativeButton("cancle",newDialogInterface.OnClickListener() {@OverridepublicvoidonClick(DialogInterface dialog,intwhich) {dialog.dismiss();}}).setPositiveButton("Ok",newDialogInterface.OnClickListener() {@OverridepublicvoidonClick(DialogInterface dialog,intwhich) {dialog.dismiss();JniTestHelper.exitApp();}}).create().show();break;}}};}
编译运行,效果如下:
转载地址: http://www.2cto.com/kf/201404/290498.html
html
本文介绍如何使用JNI实现在Cocos2d-x中C/C++与Android Java层的交互,包括获取包名并展示对话框的具体实现。
1565

被折叠的 条评论
为什么被折叠?



