我正在尝试解决Android 5.x上的Cocos2d-x键盘输入崩溃,当我从文本创建CCImage时,键盘上找到了许多表情符号(虽然有些工作,但大多数都没有。)在Android上4.x几个设备只显示损坏的文本/额外字符。崩溃的来源是JNI的NewStringUTF()调用。它根本不支持Android 5 / Lollipop中的所有2,3和4字节utf-8字符。
这次崩溃发生在cocos2d-x v2.2.6上(并在3.x上确认)使用NDK 10e和Toolchain 4.8(不确定是否有任何差别太大,我们在转移到Android之前使用9d工作室,我确信我们遇到了这个问题,但棒棒糖的使用率要低得多。)
如果您从未推送任何未经修改的utf-8符号(即坚持使用ascii),您可能永远不会看到该问题。
Log Cat:
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] string: ''
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] in call to NewStringUTF
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] from void org.cocos2dx.lib.Cocos2dxHelper.nativeSetEditTextDialogResult(byte[])
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] "GLThread 45716" prio=5 tid=14 Runnable
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] | group="main" sCount=0 dsCount=0 obj=0x12c0c6c0 self=0xf442bc00
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] | sysTid=10959 nice=0 cgrp=default sched=0/0 handle=0xf450c380
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] | state=R schedstat=( 0 0 0 ) utm=1164 stm=188 core=2 HZ=100
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] | stack=0xeed4e000-0xeed50000 stackSize=1036KB
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] | held mutexes= "mutator lock"(shared held)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #00 pc 00004e64 /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #01 pc 00003665 /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #02 pc 00271461 /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #03 pc 002534d7 /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+158)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #04 pc 000b7f5b /system/lib/libart.so (art::JniAbort(char const*, char const*)+610)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #05 pc 000b8681 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #06 pc 000bac4f /system/lib/libart.so (art::ScopedCheck::Check(bool, char const*, ...) (.constprop.129)+922)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #07 pc 000c474d /system/lib/libart.so (art::CheckJNI::NewStringUTF(_JNIEnv*, char const*)+44)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #08 pc 002a6324 /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (_JNIEnv::NewStringUTF(char const*)+40)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #09 pc 0076eb6c /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (cocos2d::BitmapDC::getBitmapFromJavaShadowStroke(char const*, int, int, cocos2d::CCImage::ETextAlign, char const*, float, float, float, float, bool, float, float, float, float, bool, float, float, float, float)+312)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #10 pc 0076f12c /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (cocos2d::CCImage::initWithStringShadowStroke(char const*, int, int, cocos2d::CCImage::ETextAlign, char const*, int, float, float, float, bool, float, float, float, float, bool, float, float, float, float)+216)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #11 pc 007aeb14 /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (cocos2d::CCTexture2D::initWithString(char const*, cocos2d::_ccFontDefinition*)+1188)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #12 pc 0072cd6c /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (cocos2d::CCLabelTTF::updateTexture()+120)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #13 pc 0072c804 /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (cocos2d::CCLabelTTF::setString(char const*)+260)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #14 pc 00523140 /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (cocos2d::extension::CCEditBoxImplAndroid::setText(char const*)+344)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #15 pc 00523474 /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (???)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #16 pc 0076fb2c /data/app/com.appsomniacs.da2.debug-1/lib/arm/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult+208)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] native: #17 pc 001dfeb1 /data/dalvik-cache/arm/data@app@com.appsomniacs.da2.debug-1@base.apk@classes.dex (Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult___3B+100)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] at org.cocos2dx.lib.Cocos2dxHelper.nativeSetEditTextDialogResult(Native method)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] at org.cocos2dx.lib.Cocos2dxHelper.access$000(Cocos2dxHelper.java:41)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] at org.cocos2dx.lib.Cocos2dxHelper$1.run(Cocos2dxHelper.java:267)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1501)
12-11 01:02:17.460 10451-10959/com.appsomniacs.da2.debug A/art: sart/runtime/check_jni.cc:65] at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1278)
Stack Trace(来自不同的测试,但同样崩溃)
Build fingerprint: 'samsung/zerofltetmo/zerofltetmo:5.1.1/LMY47X/G920TUVU3DOJ7:user/release-keys'
Revision: '11'
ABI: 'arm'
pid: 18460, tid: 18534, name: GLThread 28670 >>> com.appsomniacs.da2 <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
r0 00000000 r1 00004866 r2 00000006 r3 00000000
r4 f33a4db8 r5 00000006 r6 00000000 r7 0000010c
r8 88476100 r9 f442c800 sl 00000000 fp 12f61070
ip 00004866 sp f33a4960 lr f6f01cf9 pc f6f25c30 cpsr 600b0010
backtrace:
#00 pc 0003bc30 /system/lib/libc.so (tgkill+12)
#01 pc 00017cf5 /system/lib/libc.so (pthread_kill+52)
#02 pc 00018907 /system/lib/libc.so (raise+10)
#03 pc 000151a5 /system/lib/libc.so (__libc_android_abort+36)
#04 pc 00012fec /system/lib/libc.so (abort+4)
#05 pc 0075a275 /data/app/com.appsomniacs.da2-2/lib/arm/libcocos2dcpp.so (__gnu_cxx::__verbose_terminate_handler()+220)
#06 pc 0072a10b /data/app/com.appsomniacs.da2-
2/lib/arm/libcocos2dcpp.so (__cxxabiv1::__terminate(void (*)())+2)
#07 pc 0072a13b /data/app/com.appsomniacs.da2-2/lib/arm/libcocos2dcpp.so (std::terminate()+10)
#08 pc 0072a4ab /data/app/com.appsomniacs.da2-2/lib/arm/libcocos2dcpp.so (__cxa_pure_virtual+14)
#09 pc 0041ecc5 /data/app/com.appsomniacs.da2-2/lib/arm/libcocos2dcpp.so
#10 pc 005977ab /data/app/com.appsomniacs.da2-2/lib/arm/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult+110)
#11 pc 001dfe39 /data/dalvik-cache/arm/data@app@com.appsomniacs.da2-2@base.apk@classes.dex
答案 0 :(得分:5)
我们通过在jbyte数组中发送std :: string的内容找到了一个解决方案,并让java端为java并返回我们可以在C ++ jni端使用的jstring。对于我们来说,这些字符串来自用户键盘,我在一周内有170k崩溃,说他们在角色名称中使用表情符号并且像疯了一样聊天......并且命名他们的化身本身也导致了崩溃。因此,Android 5.x用户加入的任何大厅都会在他们的客户尝试使用相关字符呈现其他玩家名称时立即崩溃。在Android 4.x中,这不是一个问题,因为它只是打印了一些垃圾字符。
在你的c ++方面你可以做这样的事情来实现这个功能:
jstring JniHelper::getjString(const char *input) {
JniMethodInfo minfo; // JniHelper
bool hasMethod = JniHelper::getStaticMethodInfo (minfo, APPTAG_JNI_PACKAGE_NAME, "convertCStringToJniSafeString", "([B)Ljava/lang/String;");
if (!hasMethod)
{
return minfo.env->NewStringUTF(""); // TODO Tune your response to fit your needs...
}
else
{
string nativeString = std::string(input); // has a bit of a code smell, there is probably a better way.
// cite: http://stackoverflow.com/questions/27303316/c-stdstring-to-jstring-with-a-fixed-length
jbyteArray array = minfo.env->NewByteArray(nativeString.length());
minfo.env->SetByteArrayRegion(array,0,nativeString.length(),(jbyte*)nativeString.c_str());
// cite: http://discuss.cocos2d-x.org/t/jni-return-string/9982/3
jstring str = (jstring)minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID, array);
minfo.env->DeleteLocalRef(array);
return str;
}
}
在java端将其转换为java字符串并以相同的方法返回:
public static String convertCStringToJniSafeString(byte[] input) {
try {
String nativeString = new String(input, "UTF-8"); // please debate what the safest charset should be?
return nativeString;
} catch (UnsupportedEncodingException e) {
// TODO Simplistic Error handling, tune to your needs.
Log.e(APPTAG, "Couldn't convert the jbyteArray to jstring");
return ""; //JSTRING_CONVERT_FAIL
}
}
在我们的例子中,我们想要一个jstring(它被输入为修改过的UTF8)来提供给渲染方并存储以供稍后检索,返回一个空字符串只是我们在转换失败时提示我们的一个选择。
我希望这有助于某人找到方法......甚至可能是正确的方式......