quick-cocos2d-x-2.2.6的CCHTTPRequest在Android 5.0+系统上的崩溃问题

虽然是比较旧版本的quick了,但也许会有人需要此版本的项目重新编译运行在新版本Android系统上,或是有遇到类似问题可以供参考,所以此篇文章记录解决这个问题的方法。
报错的现象是在使用“network.createHTTPRequest”进行http访问的时候(也就是lua调用的CCHTTPRequest类),出现native crash,大致异常信息是“use of deleted local reference XXXX”,看下logcat中的调用栈信息可以发现是在CCHTTPRequest::setRequestMethodJava调用时导致的。
关于这个问题我以前曾经写过相关的文章:

[译]Android冰淇淋三明治ICS(4.0+)JNI局部引用的变化 – http://blog.k-res.net/archives/1525.html
Android NDK中多线程JNI的local reference释放问题 – http://blog.k-res.net/archives/1794.html

基本问题就是高版本安卓系统的JNI部分有一些关于Local Reference的改动,导致曾经没问题的JNI逻辑在新版本系统上crash,先放出修改吧,修改
lib\cocos2d-x\external\extra\platform\android\CCHTTPRequestAndroid.cpp这个文件中Android平台下对于CCHTTPRequest的实现,找到getClassID_,修改为如下所示:

static jclass getClassID_(const char *className, JNIEnv *env)
{
    JNIEnv *pEnv = env;
    jclass ret = 0;

    do 
    {
        if (! pEnv)
        {
            if (! getEnv(&pEnv))
            {
                break;
            }
        }
        
        // By K-Res for ART
        if (NULL == s_classHttp) {
            ret = pEnv->FindClass(className);
            // s_classHttp = ret;
            s_classHttp = (jclass)pEnv->NewGlobalRef(ret);
            ret = s_classHttp;
        } else {
            // ret = (jclass)pEnv->NewLocalRef(s_classHttp);
            ret = s_classHttp;
        }
        
        if (! ret)
        {
            CCLOG("Failed to find class of %s", className);
            break;
        }
    } while (0);

    return ret;
}

然后注释掉代码中所有的

methodInfo.env->DeleteLocalRef(methodInfo.classID);

原理既是去掉了已经不允许FindClass的LocalRef,改为直接保存为GlobalRef。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。