java jni表情_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()

dcbcc0bcf1743025850f405247a8f3d9.png

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

f01e0a96ded90b31606312be377fb103.png

我先让后台的同事,把所有聊天信息清理干净,这时候设备重新登录进去没有问题了。所以确定问题就是这个NewStringUTF方法引起的(但部分设备上有问题,部分设备没问题。看了一下好像是Android5.0及以后的系统就有此问题),问了其它同事,发现他们之前遇到过并且处理了。

有二种方案:一种是升级NDK,另外一种是C++传给Java时使用byte[],Java里再把byte[]转成String,避免NewStringUTF导致的崩溃。

我用的是cocos2d-x 2.x版本,找到CCImage.cpp文件,修改getBitmapFromJava方法

fd05beb2a388680bfeeae825319c2909.png

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(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(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(buf));

return buf;

}

mysql 5.5之前仅支持3个字节,如果游戏中有留言等功能要存进数据库的记录,那么你就需要过滤这些字符了,不然就会插入数据报错。

更多阅读链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值