安卓4.1版本上cc.loader.getXMLHttpRequest()导致崩溃

在安卓4.1.1的机器上,调用cc.loader.getXMLHttpRequest(); 然后send()之后程序崩溃。creator的版本是1.4.2.

代码如下:

sendRequest : function(path,data,handler,extraUrl){
            console.log("start getXMLHttpRequest");
            var xhr = cc.loader.getXMLHttpRequest();
            console.log("111 getXMLHttpRequest");
            xhr.timeout = 5000;
            var str = "?";
            for(var k in data){
                if(str != "?"){
                    str += "&";
                }
                str += k + "=" + data[k];
            }

            if(extraUrl == null){
                extraUrl = HTTP.url;
            }
            var requestURL = extraUrl + path + encodeURI(str);
            console.log("RequestURL:" + requestURL);
            xhr.open("GET",requestURL, true);
            if (cc.sys.isNative){
                xhr.setRequestHeader("Accept-Encoding","gzip,deflate","text/html;charset=UTF-8");
            }
            
            console.log("222 getXMLHttpRequest");

            xhr.onreadystatechange = function() {
                console.log("444 getXMLHttpRequest");
                if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)){
                    console.log("http res("+ xhr.responseText.length + "):" + xhr.responseText);
                    try {
                        var ret = JSON.parse(xhr.responseText);
                        if(handler !== null){
                            handler(ret);
                        }                        /* code */
                    } catch (e) {
                        console.log("err:" + e);
                        //handler(null);
                    }
                    finally{
                    }
                }
            };
            
            xhr.send();
            console.log("333 getXMLHttpRequest");
            return xhr;
        },

log如下:

08-28 17:32:34.729 15585-15652 D/cocos2d-x debug info: start getXMLHttpRequest
08-28 17:32:34.729 15585-15652 D/cocos2d-x debug info: 111 getXMLHttpRequest
08-28 17:32:34.739 15585-15652 D/cocos2d-x debug info: RequestURL:xxxxxx
08-28 17:32:34.739 15585-15652 D/cocos2d-x debug info: 222 getXMLHttpRequest
08-28 17:32:34.739 15585-15652 D/cocos2d-x debug info: 333 getXMLHttpRequest
08-28 17:32:34.789 15585-15999  A/libc: Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 15999 (Thread-2926)
08-28 17:32:35.140 214-214/? I/DEBUG: backtrace:
08-28 17:32:35.140 214-214/? I/DEBUG:     #00  pc 0000e55c  /system/lib/libc.so (strcpy+52)
08-28 17:32:35.140 214-214/? I/DEBUG:     #01  pc 007cb408  /data/data/xxxxxx/lib/libcocos2djs.so (cocos2d::network::HttpClient::processResponse(cocos2d::network::HttpResponse*, char*)+1296)

请各位牛人看看啊!多谢!

自己顶一个

你的 xhr 对象可能已经被释放了,可以在 component 中引用一下,这个在新版本应该有保护的更好。

找到问题了,是因为服务器的HTTP回应头部没带状态字符串,目前只返回200这个状态码,没有返回200 OK这个状态字符串。而cocos的HttpClient-android.cpp中调用java层的HttpURLConnection的getResponseMessage函数时,在部分低版本机型上(如4.1.1的HTC X920e)会返回nullptr,但代码没做判断,直接去进行strcpy了,导致崩溃。

解决办法有两个:

  1. 从服务器端,如果服务器使用了tomcat 8的话,就会不返回OK这个状态字符串,建议切换到tomcat 7。
  2. 从客户端源码,可以修改HttpClient-android.cpp中的判断逻辑,如果getResponseMessage返回nullptr则不进行strcpy。这部分需要重新编译预编译文件。修改后的代码如下:
    char *messageInfo = urlConnection.getResponseMessage();
    if (nullptr != messageInfo) {
        strcpy(responseMessage, messageInfo);
        free(messageInfo);
  	}

    urlConnection.disconnect();

    // write data to HttpResponse
    response->setResponseCode(responseCode);

    if (responseCode == -1)
    {
        response->setSucceed(false);
        if (nullptr != responseMessage) {
        		response->setErrorBuffer(responseMessage);
      	}
      	else {
      			response->setErrorBuffer("response code error");
      	}
    }
    else
    {
        response->setSucceed(true);
    }

修改前后对比如下图:

1赞

我用的是cocos creator 1.4.2,因为快到项目发布了,所以不便于更新版本,也许新版的creator中改正了这个问题

同样的代码目前测在android4.4及以上没出现过,如果HTTP的状态字符串不存在,getResponseMessage会返回一个长度为0的字符串,而不是空指针,但在4.1上有这个问题,看了一下安卓源码,这几个版本上HttpURLConnection的getResponseMessage函数的代码是一样的,没发现区别,也许在别的地方吧,暂时没有深究了

嗯,是有这个问题,这个之前在cocos2d-x已经有修改了。可能是漏同步到lite了。你能发一个Pull Request到https://github.com/cocos-creator/cocos2d-x-lite么,谢谢。

Pull Request
https://github.com/cocos-creator/cocos2d-x-lite/pull/786
谢谢反馈。

我在oppo手机(Android 版本4.3)上也遇到这个问题,的确如楼主所说,通过bugly排查,崩溃发生在这里

我用的creator版本: 1.5.2

所以呢?然后呢?
按照上面说的修复一下就好了啊。
或者看看PR:

1赞