今天突然接到客服那边的反馈说,有玩家反馈进游戏后不久就崩溃了,我先是怀疑网络问题,因为一连接聊天成功后就挂了。之后用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?

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的方法

emoji表情引发的JNI崩溃相关推荐

  1. 这个emoji表情可使iphone变砖

    [环球科技报道]据英国<每日邮报>1月20日报道,最近新发现了一个苹果手机的错误,当收到特定的emoji表情后,任何人都可以用简单的三个字符的文本消息使你的iphone变砖. 你可能还觉得 ...

  2. android显示ios emoji表情符号,教程:在 Android 上也能用 iOS 新 Emoji 表情

    那是一个阳光明媚的周末,我惬意的躺在床上用着我的 Android 机刷微博,看着网上那些段子手,心情无比的舒畅.直到我看见这么一条: 瞬间百万头羊驼从我心头奔过,他到底发了些什么!?为什么我看不见!! ...

  3. 使用golang的mysql无法插入emoji表情的问题

    使用golang的mysql无法插入emoji表情 场景:使用golang 调用mysql储存emoji表情报错 环境:golang:go1.13.3 orm:GORM mysql客户端:Navica ...

  4. Emoji表情图标在iOS与PHP之间通信及MySQL存储

    在某个 iOS 项目中,需要一个服务器来保存一些用户数据,例如用户信息.评论等,我们的服务器端使用了 PHP+MySQL 的搭配.在测试过程中我们发现,用户在 iOS 端里输入了 Emoji 表情提交 ...

  5. 不要小看小小的 emoji 表情

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 前言 好久没更新了,最近事比较多,或许下个月就会恢复到正常的发文频 ...

  6. php mysql emoji表情_php 让MySQL支持Emoji表情 mysql 5.5.3+

    让MySQL支持Emoji表情 mysql 5.5.3+ 让mysql支持Emoji表情,涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集. mysql 版本 5.6 1 解决 ...

  7. Emoji表情编解码库XXL-EMOJI

    2019独角兽企业重金招聘Python工程师标准>>> <Emoji表情编解码库XXL-EMOJI> 一.简介 1.1 概述 XXL-EMOJI 是一个灵活可扩展的Emo ...

  8. MySQL 字符串删除表情符_PHP处理字符中的emoji表情(判断/移除/存储)

    目录判断字符串中是否含有 emoji 表情 移除字符串中的 emoji 表情 含有 emoji 表情的字符串在 MySQL 中的储存 utf-8 编码的 emoji 表情或者某些特殊字符占用 4 个字 ...

  9. 【Android】显示Emoji表情字符

    一.下载AndroidEmoji.ttf字体 地址1:Github Android Platform 地址2:AndroidEmoji.ttf.zip 二.使用 2.1 将字体拷贝到assets/fo ...

最新文章

  1. 浮点数 IEEE表示 舍入 运算
  2. 第二次Soring冲刺计划第二天(个人)
  3. 自定义图片,实现透明度动态变化
  4. @slf4j注解_SpringBoot + Redis + 注解 + 拦截器 实现接口幂等性校验
  5. 「LibreOJ Round #11」Misaka Network 与测试 (网络流跑二分图匹配)
  6. echarts词云图形状_词云图在自然语言中的应用,可以如此炫酷!
  7. Hacker News 2018 年度报告出炉
  8. win10如何共享打印机_windows1064位系统如何连接window732位共享打印机
  9. kaggle竞赛——泰坦尼克号获救
  10. Hadoop KMS 使用
  11. 三星S5P6818之UBOOT网络配置
  12. 什么是SVC?AVC和SVC有什么区别
  13. 秋招内推码汇总第二波 | 阿里、科大讯飞等10家公司内推码
  14. python 异步io 写excel_python异步IO编程(二)
  15. Tesseract图文识别--简单
  16. ARM系统下使用Vdbench测试存储性能
  17. qq视频压缩的方法你知道吗
  18. 「科普」带你认识5G基站
  19. 利用dlib81人脸关键点提取额头脸颊ROI
  20. 转:阴影锥原理与展望—真实的游戏效果的实现

热门文章

  1. 为什么要返回softmax_为什么softmax搭配cross entropy是解决分类问题的通用方案?
  2. 83. 删除排序链表中的重复元素 golang
  3. 僵尸进程的产生,危害和解决方案
  4. C++ 使用extern C简单使用
  5. [Linux]线程安全和可重入函数
  6. 用英文单词模拟数字计算c语言,C语言程序设计用英文单词模拟数学计算
  7. 二叉树的进阶操作---(求二叉树中所有结点个数,求叶子结点个数,求第k层结点个数;在二叉树中查找某一结点;层序遍历;判断是否为完全二叉树)
  8. Java最新大厂面试真题总结,瞬间高大上了!
  9. Redis有几种数据类型?文末领取面试资料
  10. 透彻解析!字节跳动Android实习面试凉凉经,年薪超过80万!