上篇
Java调用c++,刷新CCLabelTTF
首先我们先以引擎2.2.1为例子来新建一个TestJni的项目
创建方式如下:
python create_project.py -project TestJni -package org.cocos2dx.TestJni -language cpp
如果你对创建项目有什么疑问,可以参考这遍文章:
http://blog.csdn.net/liuyuyefz/article/details/9129525
我们第一个目标是:通过java层来给C++层发送信号,然后来让我们的cocos2d-x的HelloWorld项目中的CCLabelTTF来改变显示的内容。
请相信我这只需要非常简单的几步操作。然后奇迹就会降临。
我们先来看看我们熟悉的cocos2d-x的c++代码需要添加和修改些什么。
首先我们在 HelloWorldScene.cpp 里搜索一下这段代码:
CCLabelTTF * pLabel = CCLabelTTF::create("Hello World","Arial", 24);
这是创建一个Hello World的Label,也就是我们这次的主角。
我们想要在java处通过调用一个函数,来改变这个label的值。所以我们必须把pLabel重新定义为一个全局变量。
你需要把上面那段代码替换成如下代码
pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
同时在 HelloWorldScene.h中的
public:
下添加如下代码cocos2d::CCLabelTTF * pLabel ;
第二步:我们在 HelloWorldScene.cpp 里的空白部分添加如下代码:
这个是用来改变pLabel中的显示内容
std::string HelloWorld::changeStr =" ";//添加一个全局static变量表示状态,来接收java传过来的字符串
void HelloWorld::changeText(float t)//添加一个方法来改变label的显示内容
{
if (HelloWorld::changeStr.compare(" ") !=0)//当java没有传内容过来的时候HelloWorld::changeStr 为空
{
pLabel ->setString(HelloWorld::changeStr.c_str());
HelloWorld::changeStr =" ";
}
}
同时在 HelloWorldScene.h中的
public:
下添加如下代码
static std::string changeStr;
void changeText(float t);
到此处你可以试试看在HelloWorldScene.cpp
的
bool HelloWorld::init(){
....
}
函数中的最下面添加如下代码,并且运行看看
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(HelloWorld::changeText),this, 0,false);//添加一个计时器,来动态每一帧检测一下是java有传文本过来。
到此位置运行代码,你可以看到项目跑起来了,但是还是什么都没有改变。
这个是因为我们还没有从java端来传一个字符串来通知cocos2d-x的label改变。代价也许觉得很奇怪为什么我们要开一个scheduler来不停的检测java是否有传文本过来。因为
opengl的限制,ui只能在主线程中刷新。而我们传过来的文本是通过另外一条线程。所以我们必须要在主线程中通过schedule来检测改变UI控件。
第三步:我们在 HelloWorldScene.cpp 里的空白部分添加Jni代码:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
extern
"C"
{
void Java_org_cocos2dx_TestJni_TestJni_changeTTFLabel(JNIEnv* env, jobject thiz,jstring textStr)
{
//这里java调用changeTTFLabel("Test MyLabel Change!");,这里就会被调用。jint
const char* str;
str = env->GetStringUTFChars(textStr, false);
std::string tempStr(str);
HelloWorld::changeStr = tempStr;
}
}
#endif
第一部分:
我们来分布将讲解以上代码
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#endif
以上这段代码是限定平台。这段代码之间的代码只有在编译android项目的时候才会被调用到。因为调用ios项目的时候我们不能够调用到这个之间的代码,否则会编译出错通不过。
第二部分:
必须加上extern “C”,声明以c语言的方式进行编译,因为c++和c在编译时生成的函数签名不一样,可以在网上查找相关资料,不然运行的时候会出现链接错误。
第三部分:
void Java_org_cocos2dx_TestJni_TestJni_changeTTFLabel(JNIEnv* env, jobject thiz,jstring textStr)
这边的格式规律为
Java_签名(org_cocos2dx_TestJni_)_类名(TestJni)_changeTTFLabel(在该类下要调用的函数)
下面这一段的规律
(JNIEnv* env, jobject thiz,jstring textStr)
前面两个为必写,最后jstring textStr为要传的参数。
参数可以是jstring 或者 jint 他们分别对应了java的String 或者int类型
第四部分:
const char* str;
str = env->GetStringUTFChars(textStr, false);
jstring转化为c++的 const char*
在此c++部分的代码我们已经全部完成。
在进入这个步骤之前你要先配置好所有eclipse下编译cocos2dx android环境。
参考这篇文章:http://blog.csdn.net/jackystudio/article/details/12419387
然后在
public class TestJniextends Cocos2dxActivity{
......
}
函数中最下面添加如下代码。
private static native void changeTTFLabel(String textStr);//这个是作为中介接口,提供java调用c++里面的同名JNI函数的。
最后在
protected void onCreate(Bundle savedInstanceState){
......
}
函数中最下面添加如下代码。调用changeTTFLabel("Test MyLabel Change!");
我们先进入
cocos2d-x2.2.0/projects/TestJni/proj.android
文件夹下面,编译
build_native.sh
的shell脚本来编译c++
windows下你需要有cywin来模拟linux环境
mac下面直接
./build_native.sh即可。编译成功大致为如下画面。如果编译结果中有erro,你要注意查看说明来看看c++什么地方出错了。
然后在eclipse里面编译android的java部分
方法是eclipse-》clean
最后连上真机:调试看结果label被从Hello World改变为Test MyLabel Change!
接下篇:http://blog.csdn.net/liuyuyefz/article/details/17758809