目标: 当点击系统消息框中的 "ok" 按钮时,可执行一段我们自己任意指定的c++代码...
----------------------------------------------
platform/CCCommon.h
#include <functional> // 回调类型 typedef std::function<void()> MessageBox_Callback; // 带回调的消息框 void CC_DLL MessageBox(const char * msg,const char * title,const MessageBox_Callback & callback);
platform/ios/CCCommon.mm
// 消息框代理 @interface MessageBox_Delegate : NSObject <UIAlertViewDelegate> { MessageBox_Callback mCallback; } - (id)initWithCallback:(const MessageBox_Callback &)callback; @end @implementation MessageBox_Delegate - (id)initWithCallback:(const MessageBox_Callback &)callback; { if (self = [super init]) { mCallback = callback; // 备份对象 } return(self); } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { [alertView setDelegate: nil]; [self autorelease]; mCallback(); // 回调 } @end void MessageBox(const char * msg,const MessageBox_Callback & callback) { MessageBox_Delegate * modalDelegate = [[MessageBox_Delegate alloc] initWithCallback: callback]; NSString * tmpTitle = (title) ? [NSString stringWithUTF8String : title] : nil; NSString * tmpMsg = (msg) ? [NSString stringWithUTF8String : msg] : nil; UIAlertView * messageBox = [[UIAlertView alloc] initWithTitle: tmpTitle message: tmpMsg delegate: modalDelegate cancelButtonTitle: @"OK" otherButtonTitles: nil]; [messageBox autorelease]; [messageBox show]; }
platform/android/CCCommon.cpp
void MessageBox(const char * msg,const char * title) { showDialogJNI(msg,title,0); // 回调地址为0 则不回调 } void MessageBox(const char * msg,const MessageBox_Callback & callback) { MessageBox_Callback * Callback = new MessageBox_Callback(); // 待回调后 delete *Callback = callback; // 备份对象 showDialogJNI(msg,(long long)Callback); // 将地址作为64位整型传给Java(防止日后将c++代码编译为64位版本) } extern "C" { // 供Java回调 JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHandler_onDialogButtonClicked(JNIEnv* env,jobject thiz,jlong callback) { if (0 != callback) { MessageBox_Callback * Callback = (MessageBox_Callback *)callback; (*Callback)(); // 回调之 delete Callback; // 删除对象 } } }
----------------------------------------------
Java_org_cocos2dx_lib_Cocos2dxHelper.h
extern void showDialogJNI(const char * pszMsg,const char * pszTitle,long long pCallback);
Java_org_cocos2dx_lib_Cocos2dxHelper.cpp
void showDialogJNI(const char * pszMsg,long long pCallback) { if (!pszMsg) { return; } JniMethodInfo t; if (JniHelper::getStaticMethodInfo(t,CLASS_NAME,"showDialog","(Ljava/lang/String;Ljava/lang/String;J)V")) // ** { jstring stringArg1; if (!pszTitle) { stringArg1 = t.env->NewStringUTF(""); } else { stringArg1 = t.env->NewStringUTF(pszTitle); } jstring stringArg2 = t.env->NewStringUTF(pszMsg); t.env->CallStaticVoidMethod(t.classID,t.methodID,stringArg1,stringArg2,pCallback); // 调用Java t.env->DeleteLocalRef(stringArg1); t.env->DeleteLocalRef(stringArg2); t.env->DeleteLocalRef(t.classID); } }
Cocos2dxHelper.java
public class Cocos2dxHelper { private static void showDialog(final String pTitle,final String pMessage,final long pCallback) // 供c++调用 { Cocos2dxHelper.sCocos2dxHelperListener.showDialog(pTitle,pMessage,pCallback); } public static interface Cocos2dxHelperListener // 此接口由Cocos2dxActivity实现 { public void showDialog(final String pTitle,final long pCallback); } }
Cocos2dxActivity.java
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener { @Override public void showDialog(final String pTitle,final long pCallback) { Message msg = new Message(); msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG; msg.obj = new Cocos2dxHandler.DialogMessage(pTitle,pCallback); this.mHandler.sendMessage(msg); } }
Cocos2dxHandler.java
public class Cocos2dxHandler extends Handler { private static LinkedList<DialogData> sDialogDataList = null; // c++ 回调 public static native void onDialogButtonClicked(long callback); private void showDialog(Message msg) { Cocos2dxActivity theActivity = this.mActivity.get(); DialogMessage dialogMessage = (DialogMessage)msg.obj; AlertDialog alertDialog = new AlertDialog.Builder(theActivity) .setCancelable(false) .setTitle(dialogMessage.titile) .setMessage(dialogMessage.message) .setPositiveButton("Ok",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog,int which) { if (null != sDialogDataList) { Iterator<DialogData> listItr = sDialogDataList.iterator(); while (listItr.hasNext()) // 遍历list找dialog { DialogData dialogData = listItr.next(); if (dialogData.dialog == dialog) { onDialogButtonClicked(dialogData.callback); // 回调c++ listItr.remove(); // 移除 break; } } } } }) .create(); if (null == sDialogDataList) // 初始化list { sDialogDataList = new LinkedList<DialogData>(); } DialogData dialogData = new DialogData(alertDialog,dialogMessage.callback); // Dialog与callback绑定 sDialogDataList.addFirst(dialogData); // 存入list (后弹出的对话框 会先被点击 所以放在list头部 便于查询) alertDialog.show(); } private static class DialogData // dialog及对应的callback { public DialogInterface dialog; public long callback; public DialogData(DialogInterface dialog,long callback) { this.dialog = dialog; this.callback = callback; } } public static class DialogMessage { public String titile; public String message; public long callback; public DialogMessage(String title,String message,long callback) { this.titile = title; this.message = message; this.callback = callback; } } }
调用实例
cocos2d::MessageBox("连接服务器失败","通知",[this]() { if (GGlobal::GLoginSocket->ConnectLoginServer()) // 重新请求连接 { this->mTimeUsed = 0.0f; } } );
以上源代码文件在不同版本的cocos2d-x中可能路径略微有差别,可自行搜索定位,目前只实现了Android和iOS版,仅供参考.
原文链接:https://www.f2er.com/cocos2dx/345365.html