那些年Android开发遇到的坑(JNI 之 Illegal start byte 0xfe)

公司构建了自己的推送系统,我们的app的推送也有极光推送改为了自己的推送。在使用我们自己的推送的过程中,推送纯文字一切正常,但如果推送内容中含有特殊表情(比如这样的 ),在一部分Android机器(红米3,努比亚)上就会出现异常。异常如下:

JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte 0xfe

我再网上百度了下产生的原因如下:这个异常是由于Java虚拟机内部的 dalvik/vm/CheckJni.c中的 checkUtfString函数抛出的,JVM的这个接口不支持四个字节的UTF8字符。在我的仔细检查下找到了问题发生的地方 :
jstring msg= (*env)->NewStringUTF(env, msg); 
而这msg就是jni调用java方法返回给客户端的需要处理的一个JSONString。在网上也有人给出了解决方法(调用函数之前,对接口传入的字符串进行过滤。可以参考这个链接http://www.mobibrw.com/2016/2859。但这个方法我们不可以使用(产品要求昵称可以含有表情)。Google了好久,发现了一个解决方法:让jni返回给java层byte[] ,在java层将byte[]转换成String字符串然后处理。果然在我的尝试下这个问题就这样解决了。
修改后的关键代码如下
jni层的处理如下
jmethodID g_mid = (*env)->GetMethodID(env, g_clazz,"callback","(Ljava/lang/String;[B)V");
jbyteArray byteArray = (*env)->NewByteArray(env,payload_size);
(*env)->SetByteArrayRegion(env,byteArray, 0, payload_size, payload);
(*env)->CallVoidMethod(env, g_obj, g_mid, jappid, byteArray);

java层jni调用的方法如下
public void callback(String appId, byte[] data) {
    if(data==null) return;
    String msg=new String(data);
    if (!TextUtils.isEmpty(saveLog(GPushClient.getLogFilePath(), msg);
        Intent intent = new Intent();
        intent.setAction(GPushClient.MESSAGE_RECEIVED_ACTION);
        intent.putExtra(GPushClient.EXTRA, msg);
        mContext.sendBroadcast(intent);
    }
}

第一次发博客,有什么不正确的欢迎指正,有什么疑问也可以联系我邮箱:972876901@qq.com

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值