有关cocos2dx游戏中复制与粘贴的问题(跨线程的操作)

5 篇文章 0 订阅
3 篇文章 0 订阅

有关cocos2dx游戏中android复制与粘贴的问题

一、问题的来由

问题的主要来由是在现在的游戏中需要复制用户的id号,进行游戏内查找,同时也需要支持跨APP间的复制粘贴(也就是微信中的问题可以剪切到游戏中进行粘贴搜索或者发布到聊天系统内)


二、主要的思路

主要的思路是借助安卓系统的剪切板来进行操作。但是需要注意一般的游戏中,游戏的逻辑都是新建的一个线程,所有网上很多的代码是不能直接使用的,这里涉及到跨线程的数据共享(操作)。当然这里只是提供一种思路:c++层先调用安卓的剪切板(游戏线程),进入安卓的JAVA层获取(安卓的主线程),将获取到的字符串返回到c++等(即回到游戏线程),用于显示。


三、详细的实现

1.最开始的解决方案:

c++层的调用

void main()
{ 
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
	TextField* pInput = static_cast<TextField*>(m_pWindow->getChildByPath("Root/Wnd/Page_1/Search/Input"));
	if (pInput)
	{
		DeviceManager::Instance().PasteFromClipboard();
	}
}

std::string DeviceManager::PasteFromClipboard()
{
    //粘贴功能
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
    cocos2d::log("PasteFromClipboard");
    JniMethodInfo info;
    jstring ret;
    std::string cacheData = "";
    bool bHave = JniHelper::getStaticMethodInfo(info, CLASS_NAME, "getFromClipboard", "()Ljava/lang/String;");
    if (bHave){
        ret = (jstring)info.env->CallStaticObjectMethod(info.classID, info.methodID);
        cacheData = JniHelper::jstring2string(ret);
        info.env->DeleteLocalRef(info.classID);
        info.env->DeleteLocalRef(ret);
    }
    return cacheData;
    
#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS
    return IOSHelper::pasteFromClipboard();
#endif
}

JAVA 层调用

public static String getFromClipboard() {
	final Context context = getContext();
	ClipboardManager clipboard = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);
       if(clipboard.getText() != null)
       {
          return clipboard.getText().toString();
       }
       else
      {
          return "";
      }

这里的方式可以带大多数安卓机器上运行成功,但是会有意外的,例如在三星note4上就有问题,特别是为空的之后会崩溃。

也就是这里的核心问题就是线程的不安全性,为什么这里你想想一想。


2.最后的解决方案

这里c++层的调用基本不用改,只改变JAVA层,但是思路是采用回调的这种形式,也就是当c++等调用之后,JAVA层处理好以后,再回调c++等的函数执行即可。

c++等增加回调函数

#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
extern "C" {
	JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_GetFromClipboardCallBack(JNIEnv* env, jobject clazz, jstring resultData)
	{
		const char* str = env->GetStringUTFChars(resultData, NULL);
		cocos2d::log("GetFromClipboardCallBack %s", str);

		const std::string s(str);
		StringArgs args(s);
		LOGIC_EVENT.onPasteEvent.FireEvent(args);
		cocos2d::log("GetFromClipboardCallBack111");
	}
}
#endif


JAVA层的调用

	public static String getFromClipboard() {
		//final Context context = getContext();
		//ClipboardManager clipboard = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);
		//return clipboard.getText().toString();


		Cocos2dxActivity sCocos2dxActivity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
        sCocos2dxActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
				final Context context = getContext();
				ClipboardManager clipboard = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);

				if(clipboard.getText() != null)
				{
					final String text = clipboard.getText().toString();	

					Cocos2dxActivity activity = (Cocos2dxActivity)Cocos2dxActivity.getContext();
					activity.runOnGLThread(new Runnable() {
						@Override
						public void run() {
							AppActivity.GetFromClipboardCallBack(text);
						}
					});
				}
				else
				{
					final String text = "";	
					Cocos2dxActivity activity = (Cocos2dxActivity)Cocos2dxActivity.getContext();
					activity.runOnGLThread(new Runnable() {
						@Override
						public void run() {
							AppActivity.GetFromClipboardCallBack(text);
						}
					});
				}

				//Log.e("Clipboard4", "22222222222222");
            }
        });

		return "";
	}

	public static native void GetFromClipboardCallBack(String resultData);


我这里runOnUiThread是安卓的主线程,runOnGLThread是游戏线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值