I've been paid so much time debuging it, but I can't find any solution for the bug, the following code always crashing on my galaxy S2 ( runs on android 4.1.2), I develop with cocos2d-x 2.1.5,I avoid using autorelease,release,retain.. in onHttpRequestCompleted() functions, but it still not work on my device.
help me,please! Here is my code:
#include "WuXiaUpdateScene.h"
#include "base64.h";
#include "FileOperation.h";
#include <algorithm>
#include "WuXiaLoginScene.h";
#include "WuXiaProgressBar.h"
#include "WuXiaServer.h"
#include "WuXiaMsgBox.h"
#include "StringHelper.h"
USING_NS_CC;
CCScene* WuXiaUpdateScene::scene()
{
// 'layer' is an autorelease object
WuXiaUpdateScene *layer = WuXiaUpdateScene::create();
// return the scene
return (CCScene*)layer;
}
// on "init" you need to initialize your instance
bool WuXiaUpdateScene::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init())
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
this->setFlag(UPDATE);
/////////////////////////////
// 3. add your codes below...
fileCount = 0;
fileUpdated = 0;
CCLabelTTF * checkupdatesTTF = CCLabelTTF::create("Checking updates","Arial",22);
checkupdatesTTF->setTag(1);
checkupdatesTTF->setPosition(CCPoint(visibleSize.width/2,visibleSize.height/2));
this->addChild(checkupdatesTTF);
// 建立 progress bar
WuXiaProgressBar * progressBar = WuXiaProgressBar::create();
progressBar->setTag(2);
progressBar->setPercentage(0);
status = Updating;
connect();
return true;
}
void WuXiaUpdateScene::onEnter()
{
CCLayer::onEnter();
this->schedule(schedule_selector(WuXiaUpdateScene::onUpdateCompleted),0.5);
}
void WuXiaUpdateScene::onHttpRequestCompleted(cocos2d::extension::CCHttpClient* client, cocos2d::extension::CCHttpResponse* response)
{
std::vector<char> *buffer = response->getResponseData();
char* cString = new char[buffer->size()];
for (unsigned int i=0;i<buffer->size();i++)
{
sprintf(cString+i,"%c",(*buffer)[i]);
}
std::string sString = cString;
if (response->isSucceed() && sString.find("SUCCESS") != string::npos && sString.find("#SUCCESS") != string::npos)
{
if (sString.find("NO_UPDATES") != string::npos)
{
CCLabelTTF * checkupdatesTTF = (CCLabelTTF*)this->getChildByTag(1);
if (checkupdatesTTF)
{
checkupdatesTTF->setString("No updates");
status = Updated;
}
return;
}
vector<string> fileParts = StringHelper::Split(cString,"#");
std::string writablePath = cocos2d::CCFileUtils::sharedFileUtils()->getWritablePath();
std::vector<std::string> vPaths = std::vector<std::string>();
vPaths.push_back(writablePath);
cocos2d::CCFileUtils::sharedFileUtils()->setSearchPaths(vPaths);
vector<string> fileList = StringHelper::Split(fileParts.at(3).c_str(),",");
CCLabelTTF * checkupdatesTTF = (CCLabelTTF*)this->getChildByTag(1);
char* cFileCount = new char[5];
sprintf(cFileCount,"0/%d",fileList.size());
string count(cFileCount, cFileCount+strlen(cFileCount));
string wstr;
wstr.append("There're ");
wstr.append(count);
wstr.append(" files need to be updated.");
checkupdatesTTF->setString(wstr.c_str());
version = fileParts.at(1);
fileCount = fileList.size();
for (int i=0;i<fileList.size();i++)
{
cocos2d::extension::CCHttpRequest* request = new cocos2d::extension::CCHttpRequest();
std::string version="0";
char* url= new char[1024];
sprintf(url,"%s",fileList.at(i).c_str());
request->setUrl(url);
request->setRequestType(cocos2d::extension::CCHttpRequest::kHttpGet);
request->setResponseCallback(this, httpresponse_selector(WuXiaUpdateScene::onFileDownloaded));
cocos2d::extension::CCHttpClient::getInstance()->send(request);
request->release();
delete url;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
WuXiaProgressBar * progressBar = (WuXiaProgressBar*)this->getChildByTag(2);
progressBar->setPosition(CCPoint(visibleSize.width/2,visibleSize.height/2-50));
this->addChild(progressBar);
}
}
void WuXiaUpdateScene::onFileDownloaded(cocos2d::extension::CCHttpClient* client, cocos2d::extension::CCHttpResponse* response)
{
WuXiaProgressBar * progressBar = (WuXiaProgressBar *)this->getChildByTag(2);
std::vector<char> *buffer = response->getResponseData();
cocos2d::extension::CCHttpRequest *hr = response->getHttpRequest();
const char * url = hr->getUrl();
int len = strlen("7a30a48c-bd38-46b2-bb38-4afb79ac89abi.png");
char * fileName = new char[len+1];
memcpy( fileName, &url[strlen(url)-len], len );
fileName[41] = '\0';
FileOperation::saveFile(fileName,buffer);
progressBar->setPercentage((++fileUpdated)/fileCount*100);
if (fileUpdated == fileCount)
{
// 取得版本
char* versionFile = "version.cfg";
// 儲存版本資訊
FileOperation::saveFile(versionFile,(char*)version.c_str());
CCLabelTTF * checkupdatesTTF = (CCLabelTTF*)this->getChildByTag(1);
checkupdatesTTF->setString("Update finished.");
status = Updated;
return;
}
else
{
CCLabelTTF * checkupdatesTTF = (CCLabelTTF*)this->getChildByTag(1);
char* cFileCount = new char[5];
sprintf(cFileCount,"%.0f/%.0f",fileUpdated,fileCount);
string count(cFileCount, cFileCount+strlen(cFileCount));
string wstr;
wstr.append("there're ");
wstr.append(count);
wstr.append(" files need to be updated.");
checkupdatesTTF->setString(wstr.c_str());
}
}
// connect to server and get file list to update
void WuXiaUpdateScene::connect()
{
cocos2d::extension::CCHttpRequest* request = new cocos2d::extension::CCHttpRequest();
std::string version="0";
char* url= new char[1024];
std::string versionFile = "version.cfg";
if (FileOperation::isFileAvaiable(versionFile))
sprintf(url,"%sgetUpdateFiles.aspx?text=%s",WuXiaServer::PrimaryServer,base64_encode(FileOperation::readFile(versionFile)).c_str());
else
sprintf(url,"%sgetUpdateFiles.aspx?text=%s",WuXiaServer::PrimaryServer,base64_encode("0").c_str());
request->setUrl(url);
request->setRequestType(cocos2d::extension::CCHttpRequest::kHttpGet);
request->setResponseCallback(this, httpresponse_selector(WuXiaUpdateScene::onHttpRequestCompleted));
cocos2d::extension::CCHttpClient::getInstance()->send(request);
request->release();
delete url;
}
// switch screen whem update completed
void WuXiaUpdateScene::onUpdateCompleted(float dtTime)
{
if (status != Updated)
return;
this->unschedule(schedule_selector(WuXiaUpdateScene::onUpdateCompleted));
CCScene * scene = WuXiaLoginScene::scene();
CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1,scene));
}@
I correct my answer, it's a memory issue. char* cString = new char[buffer->size()]; can not store enough char for "buffer", char* cString = new char[buffer->size()+1]; is correct, I did not consider the empty char at the end of the buffer.