Black screen after certain amount of scene changes

Hi all,

I’m currently working on a project involving a main “hub” screen with nine sub-pages accessible from the main page. On the simulator, I can open the first five scenes, in any order, without a problem, and go back to the main scene. However, after the sixth one, the background goes black, with only the “back button” image asset appearing. When I tried building it and using it on my LG smartphone, it managed to open seven scenes, with the eight scene causing the entire scene to go black. (presumably no displayobjects were loading in)

I followed the template when creating the scenes, and I exit scene by calling the removeScene() function prior to calling the gotoScene() function, to no avail. (I figured it might have been a memory issue stemming from not removing scenes.) Maybe there is a limit on creating scenes I am unaware of.

Anyone experience this issue before? If so, did you manage to find a work-around?

Any input would be appreciated.

Update: I partially solved my issue…on the simulator. When declaring the function to switch scene, I called removeScene() BEFORE calling gotoScene(), and it wasn’t actually removing the scene as a result of that scene still being active.

However, on the build I downloaded to my phone, I still have issues after applying the fix. Sometimes I go through 8 scene transition and get an index-related crash (maybe doesn’t load a display object in time and then crash when it’s modified next line?)

Other times I can cycle through all the scenes at least once before the background fails to load…I’ll keep messing with it and post updates if I figure anything else out.

It might be helpful if you shared any messages you’re getting in your console log.  In particular, you need to learn how to read the device’s console log and watch for error messages there.

Finally, you can’t remove the scene you’re currently in. I personally prefer to remove a scene **before** I go to it. So if I’m going to “sceneA”, I’ll do:

composer.removeScene("sceneA") composer.gotoScene("sceneA")

This is of course kind of a brute force way to manage this. Your old scenes hang around for a while, but code-wise it’s the simplest approach.

There is a way to make a scene self-removing. This is perhaps the best practice if you feel the urgency to always remove scenes. You can change the scene:hide() function to be:

-- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen composer.removeScene( composer.getSceneName( "current" ) ) end end

This is the one and only time you can remove the scene you’re in because at this point the scene is done and off screen so you can at this point safely remove it.

Rob

Thanks for the reply, Rob.

I applied the fix and my scenes are now self-removing. However, I am now experiencing a new error after switching a certain amount of scenes (10-15 typically).

In my scene:show() function, I declare a few display objects, and at times, when switching scenes, I will get an nil value index error. For example:

-- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen local back = display.newImageRect( sceneGroup, "BackButton.png", 150, 100)                 while back.x == nil do print("nil!") end back.x = 140 back.y = 950 back:addEventListener( "tap", changeScenes) end end

In the above block of code, I will get the error: “…/scene5.lua:49: attempt to index local ‘back’ (a nil value)” but ONLY on the built app, using my smartphone (LG G6)

Could it be taking longer than usual to declare the image, resulting in the nil error when its XY coordinates are set? If so, what is a potential workaround? I tried to investigate further using the "while back.x == nil do print(“nil”) end, but I don’t get the error on the simulator…and on the smartphone I just get a plain crash, most likely due to stack overflow.

You probably should not be using a “while” loop in line 48. A simple:

if back.x == nil then print("nil!") end

will work, though will probably still error if back itself is nil.  Normally you would test like this:

if back == nil or back.x == nil then print("nil!") end

Since the first check could be nil, it will cause the then clause to execute. If that’s not true, then it will check the back.x check next.

We really need to see the full stack trace of the crash and probably more code around it.  Can you use “adb logcat” or Android Studio and capture the results and post it here?

Rob

Wow, I have been at this for months and haven’t thought to set up logcat on my phone…I’ll definitely start doing that for mobile debugging.

At the moment, my current issue seems to be fixed. I believe I made the mistake of declaring objects in the scene:show() function, in addition to scene:create(). All the index errors were pointing to lines within the show() function, while the create() function was loading the other objects in just fine.

After moving all my declaration/positioning code from scene:show() to scene:create(), I no longer get crashes when testing the app on my phone.

Thanks again for the support, Rob.

 

Update: I partially solved my issue…on the simulator. When declaring the function to switch scene, I called removeScene() BEFORE calling gotoScene(), and it wasn’t actually removing the scene as a result of that scene still being active.

However, on the build I downloaded to my phone, I still have issues after applying the fix. Sometimes I go through 8 scene transition and get an index-related crash (maybe doesn’t load a display object in time and then crash when it’s modified next line?)

Other times I can cycle through all the scenes at least once before the background fails to load…I’ll keep messing with it and post updates if I figure anything else out.

It might be helpful if you shared any messages you’re getting in your console log.  In particular, you need to learn how to read the device’s console log and watch for error messages there.

Finally, you can’t remove the scene you’re currently in. I personally prefer to remove a scene **before** I go to it. So if I’m going to “sceneA”, I’ll do:

composer.removeScene("sceneA") composer.gotoScene("sceneA")

This is of course kind of a brute force way to manage this. Your old scenes hang around for a while, but code-wise it’s the simplest approach.

There is a way to make a scene self-removing. This is perhaps the best practice if you feel the urgency to always remove scenes. You can change the scene:hide() function to be:

-- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen composer.removeScene( composer.getSceneName( "current" ) ) end end

This is the one and only time you can remove the scene you’re in because at this point the scene is done and off screen so you can at this point safely remove it.

Rob

Thanks for the reply, Rob.

I applied the fix and my scenes are now self-removing. However, I am now experiencing a new error after switching a certain amount of scenes (10-15 typically).

In my scene:show() function, I declare a few display objects, and at times, when switching scenes, I will get an nil value index error. For example:

-- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen local back = display.newImageRect( sceneGroup, "BackButton.png", 150, 100)                 while back.x == nil do print("nil!") end back.x = 140 back.y = 950 back:addEventListener( "tap", changeScenes) end end

In the above block of code, I will get the error: “…/scene5.lua:49: attempt to index local ‘back’ (a nil value)” but ONLY on the built app, using my smartphone (LG G6)

Could it be taking longer than usual to declare the image, resulting in the nil error when its XY coordinates are set? If so, what is a potential workaround? I tried to investigate further using the "while back.x == nil do print(“nil”) end, but I don’t get the error on the simulator…and on the smartphone I just get a plain crash, most likely due to stack overflow.

You probably should not be using a “while” loop in line 48. A simple:

if back.x == nil then print("nil!") end

will work, though will probably still error if back itself is nil.  Normally you would test like this:

if back == nil or back.x == nil then print("nil!") end

Since the first check could be nil, it will cause the then clause to execute. If that’s not true, then it will check the back.x check next.

We really need to see the full stack trace of the crash and probably more code around it.  Can you use “adb logcat” or Android Studio and capture the results and post it here?

Rob

Wow, I have been at this for months and haven’t thought to set up logcat on my phone…I’ll definitely start doing that for mobile debugging.

At the moment, my current issue seems to be fixed. I believe I made the mistake of declaring objects in the scene:show() function, in addition to scene:create(). All the index errors were pointing to lines within the show() function, while the create() function was loading the other objects in just fine.

After moving all my declaration/positioning code from scene:show() to scene:create(), I no longer get crashes when testing the app on my phone.

Thanks again for the support, Rob.