emoji表情引发的JNI崩溃
今天突然接到客服那边的反馈说,有玩家反馈进游戏后不久就崩溃了,我先是怀疑网络问题,因为一连接聊天成功后就挂了。之后用logcat抓日志,发现挂在jni那里了
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()

调用JNI的NewStringUTF方法就挂了,然后让后台把聊天日志全部拉出来,另存为html放到mac机上查看。发现一个特殊的表情,如下图所示:

我先让后台的同事,把所有聊天信息清理干净,这时候设备重新登录进去没有问题了。所以确定问题就是这个NewStringUTF方法引起的(但部分设备上有问题,部分设备没问题。看了一下好像是Android5.0及以后的系统就有此问题),问了其它同事,发现他们之前遇到过并且处理了。
有二种方案:一种是升级NDK,另外一种是C++传给Java时使用byte[],Java里再把byte[]转成String,避免NewStringUTF导致的崩溃。
我用的是cocos2d-x 2.x版本,找到CCImage.cpp文件,修改getBitmapFromJava方法

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;
}
注释部分为原来的代码,将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?
Android 上的 制表符(tab) —— 一个神奇的字符 (cocos2dx crash)
Android 上的 制表符(tab) —— 一个神奇的字符 (二)
C and C++ JNI - University of Cambridge
emoji表情引发的JNI崩溃的更多相关文章
- 一个emoji引发的一条血案:mysql存储emoji表情字符时报错解决
以下是我插入一条带表情的数据到mysql后出现错误 2019-03-04 14:24:40,462 ERROR 2807 [-/139.199.27.244/-/2ms POST /api/activ ...
- 移动前端手机输入法自带emoji表情字符处理
今天,测试给我提了一个BUG,说移动端输入emoji表情无法提交.很早以前就有思考过,手机输入法里自带的emoji表情,应该是某些特殊字符.既然是字符,那应该都能提交才对,可是为啥会被卡住呢?搜了一下 ...
- JS操作Unicode编码的emoji表情显示在页面
前言:项目中用到了emoji表情,后端传递数据时直接是以Unicode形式,在页面总是无法展示,找尽各种方法总算是试出了一种,虽然达到效果但是并不是特别理解其中的原理并且无比笨拙,贴在这用作笔记,如果 ...
- IOS Emoji表情
IOS Emoji 前言:我比较喜欢有趣的东西,有一些有趣的小东西,可能不是多么多么牛逼,也可能不需要多高深的技巧,也不会为其他什么强大的功能而服务,但是有时候将很多有趣的小东西组合起来运用,比如在你 ...
- 有关emoji表情以及utf-16编码
昨日IOS组的同事遇到一个棘手的问题:当输入框内含有emoji表情时,如何获取文本框内的字符数(一个emoji表情算一个字符). 先从我最近接触的JAVA说起,JAVA中,在使用S ...
- iOS emoji表情转码 或者判断
如果项目中有评论或者信息恢复的地方,往往会用到emoji,有时候如后台不支持emoji,就会显示乱码错误,我们可以把emoji转成unicode编码或者utf8编码格式传给服务器.当然如果后台服务器接 ...
- mysql支持IOS的Emoji表情
原因: UTF-8编码有可能是两个.三个.四个字节.Emoji表情是4个字节,而Mysql的utf8编码最多3个字节,所以数据插不进去. 解决办法: 将Mysql的编码从utf8转换成utf8mb4 ...
- iOS 获取emoji表情和拦截emoji表情
1 2 //将数字转为 #define EMOJI_CODE_TO_SYMBOL(x) ((((0x808080F0 | (x & 0x3F000) >> 4) | (x &a ...
- 让mysql支持emoji表情
一.问题及原因 APP产品想对Emoji进行支持,但发现mysql数据库无法写入表情.原因是我们的mysql数据库默认用的是utf8编码,utf8编码存储时用的是三个字节,但Emoji表情是4个字节, ...
随机推荐
- ng-bind,ng-cloak优化数据显示
<div>{{text}}</div> 当我们使用angular在页面中有取值的时候,如果出现网络加载慢的问题,可能会在页面上出现{{text}}这种不好的体验,那么angul ...
- asp.net简单小爬虫
所谓爬虫简单点说,就是把别人网站上的东西爬下来,至于爬做什么用就看你自己了,比如:把别人网站上的东西爬下来放在自己网站中(感觉有点像小偷^v^). 这里随便写了一个爬虫代码(可以自己再去进行完善): ...
- Python批量修改文件名
处理语料库时,有些文件名字很不规则,为了方便处理,同义按数字顺序修改名称,主要是用到os模块: import os def RenameFiles(srcdir): #将目录下所有的文件命名为数字开头 ...
- WPF 虚拟键盘
之前做了一款WPF虚拟键盘,调用Win32的API,可以模拟键盘事件. 现将代码分享如下: 按键布局如下: <Button Name="> <StackPanel Orie ...
- Actions类的一些主要方法
下面列举一下Actions类的一些主要方法 * keyDown.模拟按键按下 * keyUp.模拟按键弹起 * click * sendKeys * doubleClick.鼠标左键双击 * ...
- Vxlan——原理
1. 为什么需要Vxlan 普通的VLAN数量只有4096个,无法满足大规模云计算IDC的需求,而IDC为何需求那么多VLAN呢,因为目前大部分IDC内部结构主要分为两种L2,L3.L2结构里面,所有 ...
- 用C写的俄罗斯方块游戏 By: hoodlum1980 编程论坛
/************************************ * Desc: 俄罗斯方块游戏 * By: hoodlum1980 * Email: jinfd@126.com * Dat ...
- [leetcode 19] Remove Nth Node From End of List
1 题目 Given a linked list, remove the nth node from the end of list and return its head. For example, ...
- SQL Server In-Memory OLTP 无损PPT分享
我在今年DTCC上SQL Server内存数据库分享 PPT.感兴趣的朋友可以看下,无闩锁的数据结构使得热区问题成为过去,并行很好的维护了CPU Cache的命中率,Native代码执行使得CPU流水 ...
- Centos6.5 下安装PostgreSQL9.4数据库
一.安装PostgreSQL源 CentOS 6.x 32bit rpm -Uvh http://yum.postgresql.org/9.4/redhat/rhel-6-i386/pgdg-cent ...