Black Screen during resume

Hi,

I know this is something that was discussed some time ago, but to be honest I cannot find anything relevant.

Currently when I suspend my game, which has quite a lot graphics loaded, it will resume for 10-15 seconds [of course depends on the device and screen resolution]. During resume it will display black screen.

The only thing I was able to do, to let my users know that there’s actually something going on, was to add native activity indicator and disable the activity timer.

I’ve tried loading images, texts etc. but I won’t be able to show them. It’s always a black screen.

Is there anything we can do about it? It looks terrible.

BTW. this is happening after resuming the app and before calling the system event with “applicationResume” type.

Krystian

So I’m going to revive this thread because I’m having the same problem.The more preloaded textures I use, the longer the black screen will last when resuming. My app uses only 24MB of memory so far, and it already takes about 2 seconds for the black screen to go away. I don’t hook into any system event callbacks.

Seems like Corona swaps out texture memory when the app is suspended, and reloads it when resumed. Is that expected behavior and is there anything I can do to fix it? I’m testing on the new Nexus 7. Should I expect it to be worse on lower-end devices?

I should note that my inmobi ads appear on top of the black screen.

Hi Wenzil

yes… Corona will try to load all of the textures into the memory again.

If you have a lot of them… it will take some time to do it.

The worst thing is that you can’t display anything to the user to let them know what is going on, because during applicationSuspend phase you don’t have enough time to do it [images etc. are not shown to the user because this requires the next frame to be displayed on screen, and it is impossible to do it during suspend].

For my app it would take up to 20-30 seconds on older devices to resume…

My solution to this problem was to release the largest imagesheets during suspend, and load them back during resume.

It took me a lot of time to handle it, because the largest imagesheets were animations of enemies, and I can have a lot of them on screen, and a lot of the game logic depends on the animation itself [phases etc etc, nevermind].

Anyway in the end I was able to release all of the enemy animations, so my game resumes in a second or two on older devices and then shows a loader which will load the removed imagesheets.

Of course you have to take into account the fact, that when you are resuming, and loading your imagesheets, user can suspend the app again… and again…

A lot of effort went into this problem on my side, a lot of time “wasted” on handling this. The effect is not ideal, but I think it’s the best I can get when using Corona.

Tip: when loading large portions of graphics at once, don’t forget to add a timer with at least 50ms between load of every imagesheet. On older [or not even older but low-end] devices you will experience out of memory errors when you try to load them all at once. You have to give the garbage collector a chance to prepare some memory for you.

phew… that’s it I think.

If you find any better way to tackle this, please share.

Thanks for sharing your solution. Hadn’t thought of that! Can you elaborate how you reload your textures during resume?

Say I need all my textures for the very next frame, reloading the assets will block the resume callback, which means I have to defer the loading until the very next frame. So I guess you set a flag in the resume callback so that next frame, you can first display a “loading” icon, load back the textures, and then proceed as normal?

(I’m assuming that blocking the resume callback results in a black screen until it is finished loading)

Also, do display objects that use loaded textures have to be removed and recreated as well?

Well you simply load the sprites like you do when your app starts.

During suspend

Pause your whole game - all timers and transitions etc.

Then you save state of all of your animations somewhere [I do that on the objects that are animated].

Then you remove all of the animations from your objects [if you decorate the sprite display object, you will have to rewrite your code to have a table, which is decorated and has one of the properties being the sprite/animation - this is what I had to do]

Then you remove the imagesheet.

During resume

You show a loading screen [I simply open a popup using director]

you load all of the assets that you have removed previously

you create all of the animations/sprites that were removed from your objects

You set all of the properties [frames etc.]

That’s more or less it.

Of course you have to do this only in case of Android.

Don’t forget to handle all of the failure scenarios, like the one I mentioned when user suspends the game when you are loading your assets.

Happy coding!

That’s very helpful, thank you! Corona should really fix this issue though. More painful than it needs to be!

I don’t think this is considered as an issue by the team.

Hi @Wenzil,

As Krystian hints, this is an inherent issue with Android and isn’t “fixable”. When an Android app gets suspended, all OpenGL textures get dumped to clear memory for the next app’s textures. When an app gets resumed, all images and text have to get reloaded into OpenGL. This is a nuance of the Android operating system and does not occur on iOS.

Best regards,

Brent Sorrentino

Ah I see. Any tips for speeding up the time it takes to reload things in OpenGL?

Should my texture files obey the power of 2 rule?

Should I avoid JPEG images?

Does texture file compression (therefore smaller size on disk) matter?

@Brent

I don’t think this is not fixable.

I think that due to your rule of doing things on Android the same way they are done on iOS makes this not fixable.

There are plenty of games, with loads of graphics, which handle app suspend/resume this pretty well. I don’t really have plenty of games on my Android phone, but I’ve got Ace Wings Online [I wanted to check how they handle lag/disconnections ;)].

I load the game, I go to menu, there’s a 3d plane and camera goes around it.

I suspend the app, open up dolphin browser and go back to ace wings - I’m instantly in the game - no loading.

Then I start my game written in Corona, I go to main menu.

There’s only one imagesheet loaded, almost nothing [especially when compared to the ace wings]. I suspend the game, open up dolphin browser and resume the game. I can see black screen for 1-2 seconds and I’m back in game.

So I’m going to revive this thread because I’m having the same problem.The more preloaded textures I use, the longer the black screen will last when resuming. My app uses only 24MB of memory so far, and it already takes about 2 seconds for the black screen to go away. I don’t hook into any system event callbacks.

Seems like Corona swaps out texture memory when the app is suspended, and reloads it when resumed. Is that expected behavior and is there anything I can do to fix it? I’m testing on the new Nexus 7. Should I expect it to be worse on lower-end devices?

I should note that my inmobi ads appear on top of the black screen.

Hi Wenzil

yes… Corona will try to load all of the textures into the memory again.

If you have a lot of them… it will take some time to do it.

The worst thing is that you can’t display anything to the user to let them know what is going on, because during applicationSuspend phase you don’t have enough time to do it [images etc. are not shown to the user because this requires the next frame to be displayed on screen, and it is impossible to do it during suspend].

For my app it would take up to 20-30 seconds on older devices to resume…

My solution to this problem was to release the largest imagesheets during suspend, and load them back during resume.

It took me a lot of time to handle it, because the largest imagesheets were animations of enemies, and I can have a lot of them on screen, and a lot of the game logic depends on the animation itself [phases etc etc, nevermind].

Anyway in the end I was able to release all of the enemy animations, so my game resumes in a second or two on older devices and then shows a loader which will load the removed imagesheets.

Of course you have to take into account the fact, that when you are resuming, and loading your imagesheets, user can suspend the app again… and again…

A lot of effort went into this problem on my side, a lot of time “wasted” on handling this. The effect is not ideal, but I think it’s the best I can get when using Corona.

Tip: when loading large portions of graphics at once, don’t forget to add a timer with at least 50ms between load of every imagesheet. On older [or not even older but low-end] devices you will experience out of memory errors when you try to load them all at once. You have to give the garbage collector a chance to prepare some memory for you.

phew… that’s it I think.

If you find any better way to tackle this, please share.

Thanks for sharing your solution. Hadn’t thought of that! Can you elaborate how you reload your textures during resume?

Say I need all my textures for the very next frame, reloading the assets will block the resume callback, which means I have to defer the loading until the very next frame. So I guess you set a flag in the resume callback so that next frame, you can first display a “loading” icon, load back the textures, and then proceed as normal?

(I’m assuming that blocking the resume callback results in a black screen until it is finished loading)

Also, do display objects that use loaded textures have to be removed and recreated as well?

Well you simply load the sprites like you do when your app starts.

During suspend

Pause your whole game - all timers and transitions etc.

Then you save state of all of your animations somewhere [I do that on the objects that are animated].

Then you remove all of the animations from your objects [if you decorate the sprite display object, you will have to rewrite your code to have a table, which is decorated and has one of the properties being the sprite/animation - this is what I had to do]

Then you remove the imagesheet.

During resume

You show a loading screen [I simply open a popup using director]

you load all of the assets that you have removed previously

you create all of the animations/sprites that were removed from your objects

You set all of the properties [frames etc.]

That’s more or less it.

Of course you have to do this only in case of Android.

Don’t forget to handle all of the failure scenarios, like the one I mentioned when user suspends the game when you are loading your assets.

Happy coding!

That’s very helpful, thank you! Corona should really fix this issue though. More painful than it needs to be!

I don’t think this is considered as an issue by the team.

Hi @Wenzil,

As Krystian hints, this is an inherent issue with Android and isn’t “fixable”. When an Android app gets suspended, all OpenGL textures get dumped to clear memory for the next app’s textures. When an app gets resumed, all images and text have to get reloaded into OpenGL. This is a nuance of the Android operating system and does not occur on iOS.

Best regards,

Brent Sorrentino

Ah I see. Any tips for speeding up the time it takes to reload things in OpenGL?

Should my texture files obey the power of 2 rule?

Should I avoid JPEG images?

Does texture file compression (therefore smaller size on disk) matter?

@Brent

I don’t think this is not fixable.

I think that due to your rule of doing things on Android the same way they are done on iOS makes this not fixable.

There are plenty of games, with loads of graphics, which handle app suspend/resume this pretty well. I don’t really have plenty of games on my Android phone, but I’ve got Ace Wings Online [I wanted to check how they handle lag/disconnections ;)].

I load the game, I go to menu, there’s a 3d plane and camera goes around it.

I suspend the app, open up dolphin browser and go back to ace wings - I’m instantly in the game - no loading.

Then I start my game written in Corona, I go to main menu.

There’s only one imagesheet loaded, almost nothing [especially when compared to the ace wings]. I suspend the game, open up dolphin browser and resume the game. I can see black screen for 1-2 seconds and I’m back in game.

I am facing this issue too. My new game is using spritesheet as much as possible, which suppose to enhance performance, but still get the long black screen. Super annoying, and is enough time for most player to quit the game.

In the other hand, my old game, which is not using spritesheet, has no such issue at all. ( however, apk size is relatively large in old game)