I had been working on my latest mobile game Hexium for quite a few months, and it was time to put it into the hands of some testers. Everything seemed to be going well, but then one of the testers said that their Android phone was giving them a warning about it consuming too much battery power when it was in the background. I had never seen this warning myself, despite already testing the app on a few Android devices of my own. He showed me the screen, and sure enough the warning was on screen and looking fairly scary. As an end user, my first instinct on seeing a warning like that for a casual game would be to simply uninstall the app. This was bad.
I looked over my code and didn’t see anything that could be causing the problem. I went to the Corona Labs web site and found this excellent article on performance and optimization. However after implementing all of the tips, the tester was still receiving the warning.
Then I found it: a timer. I had a timer that was firing every second while the game was running, to check to see if the user had earned a free life. Of course this timer didn’t need to run while the app was in the background. So I added some code to catch the applicationSuspended event and cancel the timer, and gave the updated build to the tester.
Success!! Android no longer complained about the app using battery while in the background!
Here is a block of code that contains just enough to show you what events were caught, and how I stopped and restarted the timer:
local free_life_timer local onSystem = function(event) if event.type == "applicationExit" then -- Cancel the free life timer if free_life_timer ~= nil then timer.cancel(free_life_timer) end elseif event.type == "applicationSuspend" then -- Cancel the free life timer if free_life_timer ~= nil then timer.cancel(free_life_timer) end elseif event.type == "applicationResume" then - Start a new free life timer free_life_timer = timer.performWithDelay(1000, function() update_free_lives() end, 0) end end function scene:show( event ) local phase = event.phase if ( phase == "will" ) then -- setup a system event listener Runtime:addEventListener( "system", onSystem ) elseif ( phase == "did" ) then -- Start the free life timer free_life_timer = timer.performWithDelay(1000, function() update_free_lives() end, 0) end end function scene:hide( event ) local phase = event.phase if ( phase == "will" ) then -- Cancel the free life timer timer.cancel(free_life_timer) Runtime:removeEventListener( "system", onSystem ) end end