Suspending app on iOS causes it to hang visually upon resume

We never had this issue with Cocos2d-x 1.x, but now have an issue with Cocos2d-x 2.x.

I have an app that is animating (drawing a lot to the screen each frame) and when I minimize my app by pressing the home button, then try to resume the app, I am brought back to the correct place, but the animations have stopped and even though I can “play” the game, I never see anything change. It is as if the game is active beneath a snapshot of where I was before I suspended my app. Sounds, buttons, navigation, etc are all functional, but all I see is the last frame before I suspended the app.

I assume this must be a bug introduced in the 2.0.x versions of Cocos2d-x.

Just to make sure I am handling the suspend/resume properly, here is my code in AppDelegate.cpp:

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();
    CCDirector::sharedDirector()->pause();

    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->stopAnimation();  // To ensure we aren't already started

    CCDirector::sharedDirector()->resume();

    CCDirector::sharedDirector()->startAnimation();

    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

One more thing. This does not happen every time you suspend/resume. It only happens occasionally.

It’s almost like the draw() code is on it’s own thread and occasionally when you resume it still performs all of the game logic, but doesn’t resume the drawing thread. Of course I am just guessing, for all I know there isn’t a separate draw thread.

I think the functions should be changed to

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();

    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->startAnimation();

    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

We had the other code in due to an issue with suspend/resume that another user had found fixed the issue.

Maybe that “fix” is no longer needed and is causing issues. When I get home ill find the forum post where I found the prior fix and add a link to it. I believe it had something to do with the startAnimation() potentially getting called twice in certain circumstances and causing conflicts.

I found the original article that we based our code on. It was to resolve the issue of the app restarting from the beginning on resume. The fix was for Cocos2d, but it worked for us in Cocos2d-x 1.x

http://www.cocos2d-iphone.org/forum/topic/7326

I will try it without the pause() and resume() calls, but I suspect that will cause our app to restart from the beginning when resuming.