Some questions with image load on coco2d-x 2.1.3,please give me strong back![FIXED]

英语太费尽了,我是从2.0.4升级到2.1.3,在升级前,图片加载速度虽然慢,图片比较大,android真机上等的时间比2.1.3等的比较久但不会死掉,升级之后同样的程序,同样的过程在图片加载过程中有将近%70的概率会导致真机上测试挂掉,eclipse的log为:

06-17 16:41:39.994: E/cocos2d-x assert(12528): D:2d-2.1rc0-x-2.1.3\cocos2d-2.1rc0-x-2.1.3//cocos2dx/support/zip_support/ZipUtils.cpp function:getFileData line:411
06-17 16:41:40.004: A/libc(12528): Fatal signal 11 (SIGSEGV) at 0x5b9a1000 (code=2), thread 12543 (Thread-2204)

然后对比2.0.4里边的代码(主要对比了)_initWithJpgData();因为我的图片格式是jpg的,看了注视,貌似没怎么改动,所以请问我这种情况怎么去查找原因?我现在没找到在图片加载过程中进入ZipUtils.cpp的getFileData()的位置,求大神!!!

update cocos2d-x’s verson from 2.0.4 to 2.1.3,some problems with image loading on devices, with 2.1.3 the loading speed is more quickly than with 2.0.4,this is amazing,but there is about 70% possiblity to throw exception that app is exit……….and the eclipse out log like this :

06-17 16:41:39.994: E/cocos2d-x assert(12528): D:2d-2.1rc0-x-2.1.3\cocos2d-2.1rc0-x-2.1.3//cocos2dx/support/zip_support/ZipUtils.cpp function:getFileData line:411
06-17 16:41:40.004: A/libc(12528): Fatal signal 11 (SIGSEGV) at 0x5b9a1000 (code=2), thread 12543 (Thread-2204)

give me some tips,and best wishes for you!,thanks

我找到了函数调用ZipUtil.cpp 中getFileData的入口,在CCFileUtilsAndroid.cpp中,调用getFileData的函数中进入了这个ZipFile
unsigned char* CCFileUtilsAndroid::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize);
的入口。。。。。。。

对\cocos2dx\platform\android\下的 2.0.4和2.1.3的文件,发现获取压缩包数据的方式不一样,2.0.4的是 pData = CCFileUtils::getFileDataFromZip(s_strResourcePath.c_str(), fullPath.c_str(), pSize);
2.1.3 的是 pData = s_pZipFile->getFileData(fullPath.c_str(), pSize); s_pZipFile是ZipFile*类型的数据,

《《《《“整体在Cocos社区2013年,我们基本上是以C和Lua和Javascript为主,还有HTML5。在C上面,我是把逻辑更新和绘图放到一个线程里面提高效率”》》》》,我在2013的新闻稿里发现了这句,我怀疑资源加载跟这个有关系,我游戏里地图加载是使用的是异步加载接口,另外主线程中还有一些比较大的图片在加载,两个线程同时对apk中数据进行读取时候,会不会引起谁都无法获得到资源的死锁?

06-17 21:32:07.503: D/cocos2d-x debug info(1885): GETTING FILE RELATIVE DATA: assets/map/map_s/mapFile3.plist//png大小在1024*256
06-17 21:32:07.613: D/cocos2d-x debug info(1885): GETTING FILE RELATIVE DATA: assets/map/map_s/mapFile3.png
06-17 21:32:07.643: D/cocos2d-x debug info(1885): GETTING FILE RELATIVE DATA: assets/map/map10/10_171.jpg //大小在400*400
06-17 21:32:07.653: E/cocos2d-x assert(1885): D:2d-2.1rc0-x-2.1.3\cocos2d-2.1rc0-x-2.1.3//cocos2dx/support/zip_support/ZipUtils.cpp function:getFileData line:411
06-17 21:32:07.653: E/cocos2d-x assert(1885): D:2d-2.1rc0-x-2.1.3\cocos2d-2.1rc0-x-2.1.3//cocos2dx/support/zip_support/ZipUtils.cpp function:getFileData line:411

这是log,其中mapFile3.plist是主线程加载的;
map/map10/10_171.jpg是地图,是放在子线程加载的,
结果两个都没有正确的从压缩包(apk的assets)中获取数据,然后就悲剧了,晕了,晕了,,,,,之前在2.0.4中的异步加载函数中有一段等待的设置,2.1.3中没有了,我不知道这个是不是引起这个问题的原因,求解答,看在这么晚我还在调试bug的份上。。。。。。

经长时间调试修改,结论很明确了,在android平台中,2.1.3版本使用ZipFile 的getFileData这个函数速度比CCFileUtils的getFileDataFromZip 读的快很多,但是没有充分考虑到两个线程同时访问的资源的结果,改用CCFileUtils的getFileDataFromZip读取文件数据,这个是需要获取资源锁的,就是这个是加了锁的操作,虽不会出现程序死掉,但是加载速度在android真机上慢的很,。。。。。。。。

2.1.3之所以快,是因为在CCFileUtilsAndroid.cpp中只打开了一次的ssert目录,也就是只进行了一次IO的操作,剩下的通过这个文件的“句柄”每次就可以从读取对应的文件信息,但是如果采用异步加载的时候,就会出现我说的这种情况,主线程和子线程同时加载apk包中的数据时候,就会出现主线程和子线程轮流获取到这个文件的句柄,并用来读取自己的文件数据,这时候就会出问题了,很明显假如我主线程并未读取出一个文件的完整信息的时候,这个句柄就被子线程获取用来读取子线程文件的数据的时候,这个句柄里边的值就乱了,就会出现解压出错的情况,从而直接导致程序挂掉。。。。。。。。。

41:39.994: E/cocos2d-x assert(12528): D:2d-2.1rc0-x-2.1.3\cocos2d-2.1rc0-x-2.1.3//cocos2dx/support/zip_support/ZipUtils.cpp function:getFileData line:411

在2.0.4中,每次读取一个文件信息,不管是主线程还是子线程都会重新打开一下assert文件夹,在丛中读取数据,也就是每次都会打开一次assert文件夹,并进行IO操作,打开一个文件是很比较耗时间的,同时,当这个文件被打开的时候,另外一个线程来访问这个文件夹的时候是不允许被访问的,这是每个操作系统基本功能,所以也就不会出现2.1.3中的问题,也就不会导致包挂掉,但是速度慢的会很多了

Could you paste some code you used?

unsigned char* CCFileUtilsAndroid::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
{
unsigned char * pData = 0;

if ((! pszFileName) || (! pszMode) || 0 == strlen(pszFileName))
{
return 0;
}

if (pszFileName[0] != ‘/’)
{
// // // cclog(“getting file relative data: s", pszfilename);
// // // string fullpath = fullpathforfilename(pszfilename);
// // // pdata = s_pzipfile->getfiledata(fullpath.c_str(), psize);
string s_strResourcePath = getApkPath();
string filename = string(pszFileName);
//CCLOG("filename = s”,filename.c_str());
pData = CCFileUtils::getFileDataFromZip(s_strResourcePath.c_str(), filename.c_str(), pSize);
改了2.1.3的读取apk包中资源文件的方法,改成2.0.4那样的了,不报错 速度慢

这个是异步加载地图的地方,
arkCCTextureCache::sharedTextureCache()->addImageAsync(filepath,l_cut,SEL_CallFuncO(&ark_mapTextureCacheCut::ark_mapTextureCacheCut_Callback));

CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(“map/map_s/mapFile2.plist”);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(“map/map_s/mapFile3.plist”);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(“map/map_s/curpor.plist”);
这是加载plist文件的地方,主线程中加载的东西不止这些,因为这个过程是Loading的过程,曾尝试将地图放入主线程加载,经测试在移动过程中会出现卡顿的现象,地图比较大。。。。。另外考虑对
static ZipFile *s_threadFile //位于CCFileUtilsAndroid.cpp中的一个静态全局变量

进行加锁处理,但不知道该怎么加。。。。

I will fix it ASAP, and i don’t want to add any burden to loading speed.

ok thank very much,if you improve it ,please send msg to me, and i will try some actions to fix this,wish to me!

Ok, i will.

And please use English in future in this forum.
Thank you.

Thanks,i will change it…

@Yu qing Niu, i think i fixed it in this pull request https://github.com/cocos2d/cocos2d-x/pull/2916.

Ok i’m testing

Minggo Zhang wrote:

@Yu qing Niu, i think i fixed it in this pull request https://github.com/cocos2d/cocos2d-x/pull/2916.

Thanks very much,we use the same way to fix the qusetion,but i think the method you use will slow down asyn loading on android device…. we new a resource handle for asyn loading,because we know the resource which need be load by asyn in our project,but the method will fix others asyn loading problem.

Thanks again for you msg ,and i learn many useful knowledges from cocos2d-x source code and your helps.

>> Thanks very much,we use the same way to fix the qusetion,but i think the method you use will slow down asyn loading on android device….

Why?

You can comment in github too.

Sorry,i read you code again,the methos add a new map type save zip file infs , rather than reopen a I/O for asyn every times,the method is greatefaul :stuck_out_tongue:

Thank you.
So this thread can be closed?