- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试解决 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 和工具链 4.8(不确定是否有任何差异,我们在迁移到 Android 之前使用 9d Studio 和我确信我们遇到了这个问题,但 lollipop 的使用要少得多。)
如果您从不推送任何未修改的 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)
堆栈跟踪(来自不同的测试,但同样的崩溃)
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
最佳答案
我们通过发送 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 输入)提供给渲染端并存储以供稍后检索,返回一个空字符串只是我们在转换失败时提示我们的一个选择。
我希望这可以帮助某人找到一种方法……甚至是正确的方法……
关于android - 使用许多不同种类的表情符号和语言(除了 ascii,但仍然有效的修改后的 utf-8)时,调用 C++ JNI NewStringUTF 会使 android 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34323551/
我应该在将分配的字符串传递给 NewStringUTF() 后释放它吗? 我有一些类似的代码: char* test; jstring j_test; test = some_function();
我正在编写一个 JNI 来从 Java 调用 C++ 代码。当我使用 NewStringUTF() 时它已经崩溃了。这是我的代码: __android_log_print(ANDROID_LOG_VE
我正在从事一个我应该使用 native 代码的项目。这是我项目中的部分代码。 JNIEXPORT jstring JNICALL Java_com_pkg_testcpp_NatTes_nativem
我正在编写一个简单的 OpenCV 代码来显示经过 sobel 操作后的图像。我已经包含了项目属性的所有必要路径以包含 OpenCV4Android文件夹。我解决了除一个错误之外的所有错误: 错误:M
我的 JNI 代码收到 char* src来自外部源,将其转换为 String使用 jstring jStr = env->NewStringUTF(src) , 并传递结果 jStr到上层 - Ja
我想是的,但我发现的前 12 个示例都做了一些不具有说明性的事情,比如 JNIEXPORT jstring JCALL Java_com_foo_dumbImpl(JNIEnv* env, jobje
我正在尝试使用 android 中的 JNI 将 char* 从 C++ 传递到 java。我已经尝试了多种方法来传递该数据 1) 使用 NewStringUTF: const char* data
在我的 Google Play 开发者控制台中,我看到 NewStringUTF() 中有很多崩溃,如下所示: #00 pc 00000000001b9f22 /system/lib/liba
我不知道为什么调用本地方法会抛出异常。 native 代码: JNIEXPORT jstring JNICALL Java_org_amk_lockscreen_JNIActivity_getPack
我在 JNI C/C++ 中有一个方法,它接受 jstring 并返回 jstring,如下所示, NATIVE_CALL(jstring, method)(JNIEnv * env, jobje
我正在尝试解决 Android 5.x 上的 Cocos2d-x 键盘输入崩溃问题,当时我从键盘上发现的带有许多表情符号的文本创建 CCImage(虽然有些工作,但大多数不工作。)在 Android
我是一名优秀的程序员,十分优秀!