cocos2d-x resume from background issue for android

Hi all,

I just completed my new game in cocos2dx version 3.2 and its working fine with iOS but
for some android devices i facing some problems related to handling background and foreground state.
When game is running and user press power button or home button and come back after 2-3 minutes phone showing black screen and nothing happened just background music is playing and also sometimes android showing popup that game is not responding. I used SpriteSheet in my game and it 1024X1024 pixels. Please help me.

I have written a following code in AppDelegate.cpp

void AppDelegate::applicationDidEnterBackground() {
    
	log("applicationDidEnterBackground");
    Director::getInstance()->stopAnimation();
    Director::getInstance()->pause();
    
    CocosDenshion::SimpleAudioEngine::getInstance()->pauseAllEffects();
    CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

}

void AppDelegate::applicationWillEnterForeground() {
   
	log("applicationWillEnterForeground");
    Director::getInstance()->stopAnimation();
    Director::getInstance()->resume();
    Director::getInstance()->startAnimation();

    CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    CocosDenshion::SimpleAudioEngine::getInstance()->resumeAllEffects();

}

GL context will lost on Android, but cocos2d-x record and re-set for you if you just use Sprite and internal shaders.

If you read file data by yourself and create Sprite, or you use your own shader, you should re-set it when back from background by yourself.

2 Likes

@zhangxm

If we are using GLProgramState in our custom shaders do we need to manually handle it? From what I can see in CCGLProgramState.cpp it seems that it automatically deals with that case:

GLProgramState::GLProgramState()
: _vertexAttribsFlags(0)
, _glprogram(nullptr)
, _textureUnitIndex(1)
, _uniformAttributeValueDirty(true)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    /** listen the event that renderer was recreated on Android/WP8 */
    CCLOG("create rendererRecreatedListener for GLProgramState");
    _backToForegroundlistener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { _uniformAttributeValueDirty = true; });
    Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundlistener, -1);
#endif
} 

Can you confirm it? Or more specifically can you give any concrete example of when the developer needs to manually check and react to this particular situation?

Because you used your own shaders, so you should reset it by yourself.
You can refer to tests/cpp-tests/src/ShaderTest/ShaderTest.cpp for usage.

We will try to reload developers’ shaders in next version.

1 Like

Is this issue fixed in v3.10 or should we still be manually handle recreating shaders? Also if fixed what’s the first version which introduced this fix?

The solution used in ShaderTest.cpp is not really ideal since I’ve got more than one object in the scene and they all are using same custom shader. So I’ve got to manually pick which one of them should reload the shader on recreate. I was wondering if there is a way to reload shaders only once without having to deal with these kind of stuff.

1 Like

I cansay one thing for sure, The problem is still there at 3.10.
I say because i have it and im reloading shaders manully at resume.