β

quick-cocos2d-x-2.2.6的CCHTTPRequest在Android 5.0+系统

K-Res的Blog 46 阅读

虽然是比较旧版本的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。

作者:K-Res的Blog
十年乡下技术博客
原文地址:quick-cocos2d-x-2.2.6的CCHTTPRequest在Android 5.0+系统, 感谢原作者分享。

发表评论