目标: 当点击系统消息框中的 "ok" 按钮时, 可执行一段我们自己任意指定的c++代码...
实现: 修改(或添加)代码如下,
----------------------------------------------
platform/CCCommon.h
#include
// 回调类型
typedef std::function MessageBox_Callback;
// 带回调的消息框
void CC_DLL MessageBox(const char * msg, const char * title, const MessageBox_Callback & callback);
// 消息框代理
@interface MessageBox_Delegate : NSObject
{
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 char * title, 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 char * title, const MessageBox_Callback & callback)
{
MessageBox_Callback * Callback = new MessageBox_Callback(); // 待回调后 delete
*Callback = callback; // 备份对象
showDialogJNI(msg, title, (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);
void showDialogJNI(const char * pszMsg, const char * pszTitle, 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 String pMessage, final long pCallback);
}
}
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener
{
@Override
public void showDialog(final String pTitle, final String pMessage, final long pCallback)
{
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG;
msg.obj = new Cocos2dxHandler.DialogMessage(pTitle, pMessage, pCallback);
this.mHandler.sendMessage(msg);
}
}
public class Cocos2dxHandler extends Handler
{
private static LinkedList 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 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 = 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版, 仅供参考.