展会信息港展会大全

cocos2d-x 通过JNI实现c/c++和Android的java层函数交互
来源:互联网   发布日期:2015-09-27 14:52:15   浏览:1658次  

导读: 1.JNI JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为...

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

#ifndef JNI_TEST_H

#define JNI_TEST_H

#include "cocos2d.h"

using namespace cocos2d;

void setPackageName(const char *packageName)

{

CCLog("packageName: %s", packageName);

}

void exitApp()

{

CCDirector::sharedDirector()->end();

}

#endif

调用android API接口:

HelloWorldScene.cpp

#include "HelloWorldScene.h"

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include "../proj.android/jni/hellocpp/test.h"

#endif

USING_NS_CC;

void HelloWorld::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

#ifndef TEST_H

#define TEST_H

extern "C"

{

void showTipDialog(const char *title, const char *msg);

}

#endiftest.cpp

#include "cocos2d.h"

#include

#include "platform/android/jni/JniHelper.h"

#include "test.h"

#include "JniTest.h"

#define CLASS_NAME "com/DialogBox/org/JniTestHelper"

using namespace cocos2d;

extern "C"

{

void showTipDialog(const char *title, const char *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);

}

}

void Java_com_DialogBox_org_JniTestHelper_setPackageName(JNIEnv *env, jobject thiz, jstring packageName)

{

const char *pkgName = env->GetStringUTFChars(packageName, NULL);

setPackageName(pkgName);

env->ReleaseStringUTFChars(packageName, pkgName);

}

void Java_com_DialogBox_org_JniTestHelper_exitApp(JNIEnv *env, jobject thiz)

{

exitApp();

}

}

注:这里必须加上extern “C”,声明以c语言的方式进行编译,因为c++和c在编译时生成的函数签名不一样,可以在网上查找相关资料,不然运行的时候会出现链接错误。

4.3Java部分:

c++函数调用java层函数,显示一个对话框:

JniTestHelper.java

package com.DialogBox.org;

import org.cocos2dx.lib.Cocos2dxHandler.DialogMessage;

import android.os.Handler;

import android.os.Message;

public class JniTestHelper {

private static Handler mHandler;

public static void init(Handler handler)

{

JniTestHelper.mHandler = handler;

}

public static native void setPackageName(String packageName);

public static native void exitApp();

//c++函数调用java层函数,显示一个对话框

private static void showTipDialog(final String title, final String text)

{

Message msg = mHandler.obtainMessage();

msg.what = DialogBox.SHOW_DIALOG;

DialogMessage dm = new DialogMessage(title, text);

msg.obj = dm;

msg.sendToTarget();

}

}创建一个DialogMessage.java,封装dialog要显示的数据:

package com.DialogBox.org;

public class DialogMessage {

public String title;

public String msg;

}修改主程序DialogBox.java

public class DialogBox extends Cocos2dxActivity{

public static final int SHOW_DIALOG = 0x0001;

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

JniTestHelper.init(mHandler);

JniTestHelper.setPackageName(this.getPackageName());

}

public Cocos2dxGLSurfaceView onCreateView() {

Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);

// GuideLayer should create stencil buffer

glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);

return glSurfaceView;

}

static {

System.loadLibrary("cocos2dcpp");

}

//显示对话框的函数

private Handler mHandler = new Handler()

{

@Override

public void handleMessage(Message msg) {

switch(msg.what)

{

case SHOW_DIALOG:

DialogMessage dm = (DialogMessage)msg.obj;

new AlertDialog.Builder(DialogBox.this)

.setTitle(dm.titile)

.setMessage(dm.message).setNegativeButton("cancle", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

}

})

.setPositiveButton("Ok",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

JniTestHelper.exitApp();

}

})

.create().show();

break;

}

}

};

}

编译运行,效果如下:

赞助本站

人工智能实验室
AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港