Spontaneous unload of resources

Hi, I’m on the way to finish my first game, but now I ran into little problem.
The scheme is this: Main menu scene > Level select scene> Loading scene -> Game scene. On loading scene I preload all resources like sprites, sounds, etc. But one of my test devices (HTC Desire, Android 2.2.2) unloads resources after loading, so when the game tries to play some sound or draw sprite, it freezes for a moment to load the resource again.
This problem appers only on HTC Desire, I didn’t met this problem on my other devices (Samsung Galaxy Ace, Android 2.3.6 & Acer A100 tab, Android 4.0.3).

Can someone tell me why this happens? Thanks.

P.S.: I’m using Cocos2dx-2.0.4

Still waiting for help…

Try using CCTextureCache::sharedTextureCache()->dumpCachedTextureInfo() and the latest version :slight_smile:

01-29 15:18:36.111: D/cocos2d-x debug info(7579): cocos2d: CCTextureCache dumpDebugInfo: 53 textures, for 103840 KB (101.41 MB)

hmmm… All textures seems to be loaded ok, but why it keeps freezing? Maybe problem is in another place.

Try disabling sounds and if it still freezes - try adding sprite frames from your sprite sheets (assuming that you’re using them) to CCSpriteFrameCache before you go to scene.

I really wonder what are you going to do with 100 mb of textures…

Sometimes, when a scene is destroyed, all unused assets are automatically purged from the cache if you unload some assets.

Normally there are only two possibilities for resources to be unloaded: if you do it by your hand and if app gets memory warning. Otherwise such “automatic unloading” should be considered as a bug, because it obviously will cause crashes.

Victor Komarov wrote:

Try disabling sounds and if it still freezes - try adding sprite frames from your sprite sheets (assuming that you’re using them) to CCSpriteFrameCache before you go to scene.
>
I really wonder what are you going to do with 100 mb of textures…

This is how I preload resources:

for (.....)
{
            CCString* file = CCString::create(path.c_str());
            if(file) {
                CCTexture2D* texture = CCTextureCache::sharedTextureCache()->addImage(file->getCString());
            }
}

I’ve also tried like this, but it gives the same result:

for (.....)
{
            CCString* file = CCString::create(path.c_str());
            if(file) {
                CCSpriteFrame* frame = new CCSpriteFrame();
                CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFrame(frame, file->getCString());
                frame->retain();
            }
}

In both ways CCTextureCache::sharedTextureCache()->dumpCachedTextureInfo() says that all textures are loaded:

01-29 15:18:36.111: D/cocos2d-x debug info(7579): cocos2d: CCTextureCache dumpDebugInfo: 53 textures, for 103840 KB (101.41 MB)

I also tried to reduce amount of preloaded textures to 31 (42.76 MB), but nothing changed.

P.S.: I repeat, this problem appers only on HTC Desire …

When you call addImage method you only start the process and you don’t actually know when it will end, and depending on your device loading textures can take different amounts of time. Try using addImageAsync - that method allows you to get a callback after everything is loaded. You can easily find a sample in TestCpp. The scheme is as follows:
start loading N textures > show smth like LOADING…> get N callbacks > addSpriteFrame> proceed further

Hope that helps

OK, guys, thank you all, I’ve finally found the solution for my problem. Maybe it’s kinda stupid, but I don’t see the other way.
I simply create a sprite for each texture and append all of this sprites as children to the loading screen :slight_smile:

Have you tried addImageAsync?

Victor Komarov wrote:

Have you tried addImageAsync?

Yes, I’ve tried everything that has been said in this thread. I think (maybe) the cause of problem is android 2.2 garbage collector.
The most helpful advice was to upgrade cocos2dx to latest version, it helped me with another bug, but it is another story. Thank you, comrad :slight_smile:

Can you make something like a sample, reproducing your issue, and share it somehow?

Victor Komarov wrote:

Can you make something like a sample, reproducing your issue, and share it somehow?

ok, I’ll do it a little bit later

Did you try this?
CCTextureCache::sharedTextureCache()->removeUnusedTextures();

Eondo Lee wrote:

Did you try this?
CCTextureCache::sharedTextureCache()->removeUnusedTextures();

yes

Here is an example representing my issue: https://docs.google.com/file/d/0BzgdeD7CX76bTTh2Unc0Y2lKNzQ/edit?usp=sharing

Looked through your code, here are some thoughts:

        [...]

        step = 0;
        schedule(schedule_selector(Loading::loadStep), 1.0f/60.0f);

    return true;
}

void Loading::loadStep(float time)
{
        CCTexture2D* texture = NULL;
        switch (step)
        {
        case 0: texture = CCTextureCache::sharedTextureCache()->addImage("grossini.png");
                break;
        case 1: texture = CCTextureCache::sharedTextureCache()->addImage("Untitled-1.png");
                break;
        case 2: texture = CCTextureCache::sharedTextureCache()->addImage("Untitled-2.png");
                break;
        case 3: texture = CCTextureCache::sharedTextureCache()->addImage("Untitled-3.png");
                break;
        case 4: 
                {
                        CCScene *pScene = HelloWorld::scene();
                        CCDirector::sharedDirector()->replaceScene(pScene);
                }
                break;
        }
        update(time);
        ++step;
}

Here you assume that loading of one resource file takes exactly 1/60 of a second which is obviously not true in a common case - you just don’t know how long will it take for a resource to load, because it depends on the hardware and current memory state. I think If you’ll dump texture cache before going to another scene you will clearly see that some resources are missing. Try switching to loadImageAsync() - with it you can be sure that all resources are loaded properly.