emoji表情引发的JNI崩溃
2015-11-12 19:46
357 查看
今天突然接到客服那边的反馈说,有玩家反馈进游戏后不久就崩溃了,我先是怀疑网络问题,因为一连接聊天成功后就挂了。之后用logcat抓日志,发现挂在jni那里了
调用JNI的NewStringUTF方法就挂了,然后让后台把聊天日志全部拉出来,另存为html放到mac机上查看。发现一个特殊的表情,如下图所示:
我先让后台的同事,把所有聊天信息清理干净,这时候设备重新登录进去没有问题了。所以确定问题就是这个NewStringUTF方法引起的(但部分设备上有问题,部分设备没问题。看了一下好像是Android5.0及以后的系统就有此问题),问了其它同事,发现他们之前遇到过并且处理了。
有二种方案:一种是升级NDK,另外一种是C++传给Java时使用byte[],Java里再把byte[]转成String,避免NewStringUTF导致的崩溃。
我用的是cocos2d-x 2.x版本,找到CCImage.cpp文件,修改getBitmapFromJava方法
[/code]
注释部分为原来的代码,将string替换为byte[]再传给Java即可,其它地方如果也遇到JNI崩溃的问题,也按上面进行修改即可。
符一个字符串与jbyteArray的互转函数
mysql 5.5之前仅支持3个字节,如果游戏中有留言等功能要存进数据库的记录,那么你就需要过滤这些字符了,不然就会插入数据报错。
更多阅读链接:
JNI UTF-8 encoding bug with some characters
Android ICS 4.0 NDK NewStringUTF is crashing down the App
A correct way to convert byte[] in java to unsigned char* in C++, and vice versa?
emoji处理方式大起底
cocos2d-x android游戏使用自己的字体
Android 上的 制表符(tab) —— 一个神奇的字符 (cocos2dx crash)
Android 上的 制表符(tab) —— 一个神奇的字符 (二)
Java Native Interface
C and C++ JNI - University of Cambridge
Java Native Interface
探索在Android中使用Emoji Font的方法
JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte 0xf0
string: ''
in call to NewStringUTF
from void org.cocos2dx.lib.Cocos2dxRenderer.nativeRender()
string: ''
in call to NewStringUTF
from void org.cocos2dx.lib.Cocos2dxRenderer.nativeRender()
调用JNI的NewStringUTF方法就挂了,然后让后台把聊天日志全部拉出来,另存为html放到mac机上查看。发现一个特殊的表情,如下图所示:
我先让后台的同事,把所有聊天信息清理干净,这时候设备重新登录进去没有问题了。所以确定问题就是这个NewStringUTF方法引起的(但部分设备上有问题,部分设备没问题。看了一下好像是Android5.0及以后的系统就有此问题),问了其它同事,发现他们之前遇到过并且处理了。
有二种方案:一种是升级NDK,另外一种是C++传给Java时使用byte[],Java里再把byte[]转成String,避免NewStringUTF导致的崩溃。
我用的是cocos2d-x 2.x版本,找到CCImage.cpp文件,修改getBitmapFromJava方法
[code]bool getBitmapFromJava(const char *text, int nWidth, int nHeight, CCImage::ETextAlign eAlignMask, const char * pFontName, float fontSize) { JniMethodInfo methodInfo; if (! JniHelper::getStaticMethodInfo(methodInfo, "org/cocos2dx/lib/Cocos2dxBitmap", "createTextBitmap", "([BLjava/lang/String;IIII)V")) { CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__); return false; } /**create bitmap * this method call Cococs2dx.createBitmap()(java code) to create the bitmap, the java code * will call Java_org_cocos2dx_lib_Cocos2dxBitmap_nativeInitBitmapDC() to init the width, height * and data. * use this appoach to decrease the jni call number */ int strLen = strlen(text); jbyteArray byteArray = methodInfo.env->NewByteArray(strLen); methodInfo.env->SetByteArrayRegion(byteArray, 0, strLen, reinterpret_cast<const jbyte*>(text)); // jstring jstrText = methodInfo.env->NewStringUTF(text); jstring jstrFont = methodInfo.env->NewStringUTF(pFontName); methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, byteArray, jstrFont, (int)fontSize, eAlignMask, nWidth, nHeight); // methodInfo.env->DeleteLocalRef(jstrText); methodInfo.env->DeleteLocalRef(byteArray); methodInfo.env->DeleteLocalRef(jstrFont); methodInfo.env->DeleteLocalRef(methodInfo.classID); return true; }
[/code]
注释部分为原来的代码,将string替换为byte[]再传给Java即可,其它地方如果也遇到JNI崩溃的问题,也按上面进行修改即可。
符一个字符串与jbyteArray的互转函数
jbyteArray as_byte_array(unsigned char* buf, int len) { jbyteArray array = env->NewByteArray(len); env->SetByteArrayRegion(array, 0, len, reinterpret_cast<jbyte*>(buf)); return array; } unsigned char* as_unsigned_char_array(jbyteArray array) { int len = env->GetArrayLength(array); unsigned char* buf = new unsigned char[len]; env->GetByteArrayRegion(array, 0, len, reinterpret_cast<jbyte*>(buf)); return buf; }
mysql 5.5之前仅支持3个字节,如果游戏中有留言等功能要存进数据库的记录,那么你就需要过滤这些字符了,不然就会插入数据报错。
更多阅读链接:
JNI UTF-8 encoding bug with some characters
Android ICS 4.0 NDK NewStringUTF is crashing down the App
A correct way to convert byte[] in java to unsigned char* in C++, and vice versa?
emoji处理方式大起底
cocos2d-x android游戏使用自己的字体
Android 上的 制表符(tab) —— 一个神奇的字符 (cocos2dx crash)
Android 上的 制表符(tab) —— 一个神奇的字符 (二)
Java Native Interface
C and C++ JNI - University of Cambridge
Java Native Interface
探索在Android中使用Emoji Font的方法
相关文章推荐
- 【BZOJ】4130: [PA2011]Kangaroos【KD树——最长连续1的子段长度】
- nyoj 阶乘的0 84 (简单数学转换)
- MySql 数据库编程 笔记
- java程序员第一课 html 网页标签
- 工厂设计模式
- Codeforces Testing Round #12 B. Restaurant 贪心
- 浅析JQuery中的html(),text(),val()区别
- Java [leetcode 33]Search in Rotated Sorted Array
- Openwrt 3G模块
- vmware安装增强功能
- swift存储策略实践
- 转载:java面试题(一)
- Apache-POI读取Excel2003和Excel2007中数据。
- tinyhttpd-0.1.0源码分析
- 移动端图片格式调研
- Android基础入门教程——10.8 LayoutInflater(布局服务)
- 32位linux系统调用
- OC14_OC结业考试错题集
- 鸟哥的LINUX私房菜基础篇第三版 阅读笔记 三 Linux磁盘与文件系统管理
- loadrunner直接压post请求loadrunner直接压post请求