Cocos2d-x中提供了一个JniHelper类来让我们对Jni进行操作。
(PS:弄了一天想自己写代码操作Jni的,但是总是出错,技术差不得不使用Cocos2d-x现成的了)。
我们有一个Android工程 :CocosDemoAndroid
还有一个Win32工程:Cocos2dDemo.win32
这个是必备的。。。
在C++ Win32工程中有一个Scene,点击按钮调用Jni函数。
void CallJni::getInputCallBack(CCObject* pSender) { g_AndroidPlatform.showDialog(); }
这个 g_AndroidPlatform.showDialog(); 在这个函数里面 使用JniHelper类来使用Jni 。
void AndroidPlatform::showDialog() { CCLog("showDialog"); #ifdef ANDROID //下面是利用jnihelper类来调用Android Static JniMethodInfo methodInfo; //jni函数信息结构体 /*getStaticMethodInfo获取到MethodId和ClassId,ClassID通过穿进去的Activity即类名获取,MethodId通过函数名获取*/ bool isHave=JniHelper::getStaticMethodInfo(methodInfo,"com/example/cocosdemoandroid/MainActivity","showMessage","()V"); if(isHave) { /*调用这个函数*/ methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID); } #endif }
C++层关键的代码就是这两个了,在使用JniHelper的时候不要忘记加上头文件
#ifdef ANDROID #include<jni.h> #include"platform/android/jni/JniHelper.h" #endif
下面来看Android层代码了。
从上面的C++代码中也能看得出来
工程包名 : com.example.cocosdemoandroid
Activity:MainActivity
public class MainActivity extends Cocos2dxActivity { public static Context mContext; /*****消息类型****/ private static final int SHOW_MESSAGE = 0; private static Handler handler=new Handler() { @Override public void handleMessage(Message msg) { //接受消息然后去做相应的事情 if(msg.what==SHOW_MESSAGE) { Log.d("CocosDemoAndroid",String.valueOf(msg.obj)); //获取到Handler传递的参数数据 AlertDialog.Builder builder=new Builder(mContext); builder.setTitle("C++调用Android"); builder.setMessage("C++调用Android显示弹出框"); builder.show(); } super.handleMessage(msg); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext=MainActivity.this; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main,menu); return true; } public static void showMessage() { Log.d("showMessage","showMessage"); Message msg=new Message(); msg.what=SHOW_MESSAGE; msg.obj="showmessage demos"; //可以传递参数 handler.sendMessage(msg); } public native int InitJni(); static { System.loadLibrary("CocosDemo"); } }
对于Android:
为什么要使用Handle sendMessage() ??
因为如果直接在showMessage中弹出提示框,会崩溃提示 Can'tcreatehandleinsidethreadthathasnotcalledLooper.prepare()
再附上的 Android.mk 文件:
LOCAL_PATH := $(call my-dir) RAKNET_LIB_PATH := ../../../../RakNet_PC-4.08/Android/obj/local/$(TARGET_ARCH_ABI)/libRakNet.a $(call import-add-path,$(Cocos2d)) \ $(call import-add-path,$(Cocos2d)\cocos2dx\platform\third_party\android\prebuilt) \ include $(CLEAR_VARS) LOCAL_MODULE := libRakNet LOCAL_SRC_FILES :=$(RAKNET_LIB_PATH) include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := CocosDemo_shared LOCAL_CFLAGS := -w -DANDROID -DRAPIDXML_NO_EXCEPTIONS LOCAL_MODULE_FILENAME := libCocosDemo LOCAL_SRC_FILES := jni.cpp \ ../../Classes/TristanaLayer.cpp \ ../../Classes/AppDelegate.cpp \ ../../Classes/HelloWorldScene.cpp \ ../../Classes/CControlTest.cpp \ ../../Classes/CocosDemoMenu.cpp \ ../../Classes/CCScrollViewTest.cpp \ ../../Classes/CocosRakNet.cpp \ ../../Classes/MissCardSprite.cpp \ ../../Classes/MoveWithMouse.cpp \ ../../Classes/TransCards.cpp \ ../../Classes/AndroidPlatform.cpp \ ../../../public/network/MissGameNetWork.cpp \ ../../Classes/CallJni.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \ $(LOCAL_PATH)/../../../public \ $(LOCAL_PATH)/../../../public/network \ $(RakNet)/Source \ $(Cocos2d)/cocos2dx \ $(Cocos2d)/cocos2dx/include \ $(Cocos2d)/cocos2dx/kazmath/include \ $(Cocos2d)/cocos2dx/platform/android \ $(Cocos2d)/cocos2dx/platform/third_party/android \ $(Cocos2d)/external \ $(Cocos2d)/CocosDenshion/include \ $(Cocos2d)/CocosDenshion/android \ $(Cocos2d)/extensions \ $(Cocos2d)/extensions/GUI/CCControlExtension \ LOCAL_STATIC_LIBRARIES := libRakNet LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static include $(BUILD_SHARED_LIBRARY) $(call import-module,CocosDenshion/android) \ $(call import-module,cocos2dx) \ $(call import-module,extensions)
最后上效果图:
来自:http://www.tuicool.com/articles/jq2If2