接上篇http://blog.csdn.net/liuyuyefz/article/details/17754025
c++ 调用java 篇:
c++调用java。刷新android的Edit View控件
第一步:在引擎库中CocosdxActivity类中把FrameLayout 设置为全局变量
第二步:创建一个文本编辑框的布局文件
参考代码如下:
<?xmlversion="1.0"encoding="utf-8"?>
<EditTextxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dip"
android:layout_height="60dip"
android:layout_marginLeft="20dp"
android:layout_marginTop="200dp"
android:layout_marginRight='20dp'
android:layout_marginBottom='20dp'
>
</EditText>
第三步:在TestJni中申明一个全局的编辑框
参考代码如下:
public static EditText myView;
第四步:把刚才申明的文本编辑框放入LayoutInflater中,然后添加到cocos2d-x的framelayout
参考代码如下:
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myView =(EditText)LayoutInflater.from(this).inflate(R.layout.myedit,framelayout,false);
myView.addTextChangedListener(watcher);
myView.setMovementMethod(ScrollingMovementMethod.getInstance());
framelayout.addView(myView);
第五步:为文本框添加监听,当文本框状态发生改变时将调用此回调函数
参考代码如下:
TextWatcher watcher = new TextWatcher()
{
@Override
public void afterTextChanged(Editable s)
{
// TODO Auto-generated method stub
Log.d("TAG","111111");
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
// TODO Auto-generated method stub
Log.d("TAG","22222");
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
Log.d("TAG","33==[TextWatcher][onTextChanged]"+s);
}
};
第六步:建立一个消息传递函数,同时创建一个消息接收的handle。用来发送c++过来的消息,回到主线程来通知ui刷新(直接在其它线程刷新主线程ui会崩溃)
参考代码如下:
public static void hideAdView(String[] str)
{
mHandler.obtainMessage( 100, str ).sendToTarget();
}
private static HandlermHandler =new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 100://UPDATE_UI:
{
String[] arrStrings = (String[])msg.obj;
if(arrStrings[0].equals("I'm a titile"))
{
TestJni.this.myView.setText("C++ Change Java EditView string Test!");
}
}
break;
default:
break;
}
}
};
补充:下面是两个改变输入框状态的备用函数
//myView.setBackgroundColor(Color.TRANSPARENT);//改变背景色透明
//framelayout.removeView(myView);//移除控件
C++部分代码
第一步:建立发送信息的Jni
参考代码如下:(下面我将要对这段代码详细讲解)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"//引入Jni帮助头文件才能正常运行
void HelloWorld::goJava()
{
JniMethodInfo jmi;
if(JniHelper::getStaticMethodInfo(jmi ,"org/cocos2dx/TestJni/TestJni" ,"hideAdView" ,"([Ljava/lang/String;)V"))
{
jclass str_cls = jmi.env->FindClass("java/lang/String");
jstring str1 = jmi.env->NewStringUTF("I'm a titile");
jstring str2 = jmi.env->NewStringUTF("Are yor exit game?");
jobjectArray arrs = jmi.env->NewObjectArray(2 , str_cls , 0);
jmi.env->SetObjectArrayElement(arrs , 0 , str1);
jmi.env->SetObjectArrayElement(arrs , 1 , str2);
jmi.env->CallStaticVoidMethod(jmi.classID , jmi.methodID , arrs);
}
}
#endif
第一部分:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#endif
这是一个限制平台范围的宏语句,因为我们不希望在ios的代码中出现调用android的代码,所以我们把我们的代码放在如果为android平台上的时候执行,就不会影响其它平台工作。
第二部分:
如下代码讲解:
JniMethodInfo jmi;
if(JniHelper::getStaticMethodInfo(jmi ,"org/cocos2dx/TestJni/TestJni" ,"hideAdView" ,"([Ljava/lang/String;)V"))
1,以上代码具有普遍性,大多数的jni格式都如此JniMethodInfo表示声明一个方法,
2,下面 JniHelper::getStaticMethodInfo 我们就会把这个方法赋值给我们要执行的java里面的“hideView”方法
3,"org/cocos2dx/TestJni/TestJni" 部分的规律就是
“包名org/cocos2dx/TestJni/要执行方法所在的的类的类名TestJni”
4,"hideAdView" 为java那边继承过来的方法。
5,"([Ljava/lang/String;)V"))
规定返回值的类型
6,
jclass str_cls = jmi.env->FindClass("java/lang/String");
导入jni的String工具库
7,创建两个jni的string
jstring str1 = jmi.env->NewStringUTF("I'm a titile");
jstring str2 = jmi.env->NewStringUTF("Are yor exit game?");
8,初始化创建一个数组
jobjectArray arrs = jmi.env->NewObjectArray(2 , str_cls , 0);
9,为数组添加两个sring
jmi.env->SetObjectArrayElement(arrs , 0 , str1);
jmi.env->SetObjectArrayElement(arrs , 1 , str2);
10,调用java的方法,并且把刚才的数组作为一个参数传递过去
jmi.env->CallStaticVoidMethod(jmi.classID , jmi.methodID , arrs);
最后在我们建立的helloWorld程序的将要被执行到的任意地方调用Jni方法。
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
goJava();
#endif
然后编译c++和android就可以真机调试看到结果了。