前提条件:
1.操作的游戏工程和cocos2d_x游戏引擎是一个目录的
2.跟jni相关的C++代码文件放在proj.android\jni\hellocpp目录下,每加一个cpp文件,都需在proj.android\jni的Andriod.mk文件中添加:
这个在 c++调用 java 的时候是为了容易找到,所以在 hellocpp 目录下,当然可以放到其他目录
3.跟jni相关的java代码文件放在proj.android\src目录下,可以另外建立一个文件夹,比如 ioss
【一】C++调用Andriod接口
1、定义一个.h文件“test.h”,内容:
#ifndef __jnihe__test__ #define __jnihe__test__ #include <stdio.h> extern "C" { void showExitPt(const char *title,const char *msg); } #endif /* defined(__jnihe__test__) */
2.定义一个.cpp文件“test.cpp”,内容:
// // test.cpp // jnihe // // Created by admin on 15/7/6. // // #include "test.h" #include "cocos2d.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include <jni.h> #include "platform/android/jni/JniHelper.h" //表示proj.android/src/ios/JniTestHelper.java的,在该文件里有showTipDialog的实现 #define CLASS_NAME "ioss/jnitesthelper" //事实上,showExitPt一般都是跟showTipDialog同名的,这里为了区分,写成不一样 void showExitPt(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); //根据该方法的返回值调用对应的CallStaticxxxMethod方法,如CallStaticIntMethod t.env->CallStaticVoidMethod(t.classID, t.methodID, jTitle, jMsg); t.env->DeleteLocalRef(jTitle); t.env->DeleteLocalRef(jMsg); } } #endif
3.java实现,这里就是c++调用安卓工程里面的showTipDialog这个功能。
定义一个JniTestHelper.java文件,就是在刚才的proj.android\src目录下的自己建的那个文件夹里面建立一个JniTestHelper.java文件。
也可以使用 eclipse新建一个类
内容:
package ioss; import android.os.Message; public class jnitesthelper { public static void showTipDialog(final String title, final String text) { System.out.println("sssssssssssssssss"); } }
4.程序使用
这时候调用showExitPt,就会自动调用安卓的 showTipDialog 这个方法了,就会输出 ssssss
#include "HelloWorldScene.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "../proj.android/jni/hellocpp/test.h" #endif USING_NS_CC; CCScene* HelloWorld::scene() { CCScene *scene = CCScene::create(); HelloWorld *layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { // 1. super init first if ( !CCLayer::init() ) { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 , origin.y + pCloseItem->getContentSize().height/2)); CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24); pLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height - pLabel->getContentSize().height)); this->addChild(pLabel, 1); CCSprite* pSprite = CCSprite::create("HelloWorld.png"); pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); this->addChild(pSprite, 0); return true; } void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) { } #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) { showExitPt("ss","ssss"); } #endif }
【二】Andriod调用C++接口
1.在test2.h中加入实现内容:
#ifndef __jnihe__test2__ #define __jnihe__test2__ #include <stdio.h> #ifdef __cplusplus extern "C" //这个很重要 { #endif void setout(const char*); #ifdef __cplusplus } #endif #endif /* defined(__jnihe__test2__) */
2.在test2.cpp中加入实现内容:将C++实现与Andriod工程中的声明关联
#include "cocos2d.h" USING_NS_CC; #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include <jni.h> #include "platform/android/jni/JniHelper.h" #ifdef __cplusplus extern "C" { #endif void setout(const char*s) { CCLOG("mmmmmmmmmmmmmmmmmmmmm"); } //1.Java_:是格式,必须加的 //2.ioss_jnitesthelper:是路径proj.android\src\ios\jnitesthelper.java去掉proj.andriod\src的部分 //3.setoutsm:是Andriod工程中声明的名字 //4.中间需要_分开 void Java_ioss_jnitesthelper_setoutsm(JNIEnv *env,jobject thiz) { setout("s"); } #ifdef __cplusplus } #endif #endif
3.Andriod工程中的声明(JniTestHelper.java):
package ioss; import android.os.Message; public class jnitesthelper { //这个调用功能就是接着上面的那个例子,点击按钮,输出 ssss,并且调用外面的setoutsm函数,输出其他东西,从而证明调用了 public static void showTipDialog(final String title, final String text) { System.out.println("sssssssssssssssss"); jnitesthelper.setoutsm(); } public static native void setoutsm();//这句就是声明的函数,native 关键字的作用就是声明这个 setoutsm 函数是在 java 外实现的 }
4.程序调用:
程序调用这里就是上面的那句jnitesthelper.setoutsm();就是点击按钮开始调用,会输出 c++的 mmmm
【三】demo 下载
Github下载地址:https://github.com/DamonHu/jniDemo
GitOsc下载地址:http://git.oschina.net/DamonHoo/jniDemo
参考链接
原文作者:何卫
转载请注明,原文链接:http://www.cnblogs.com/hewei2012/p/3376616.html
本文在原文的基础上运行后修改,感谢原文作者的说明
版权属于:东哥笔记 - DongGe.org
本文链接:https://dongge.org/blog/177.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!