Engine exit seems to be killing the application rather than just the activity

Create issue
Issue #88 resolved
Karthik T created an issue

We are embedding this engine into our application, and I am noticing that when the game ends gracefully, it appears to kill the entire app process and not just GameActivity. Backstory at Stack overflow. I have a class MainActivity which launches GameActivity. When the game has ended, it appears that MainActivity is killed, and then restarted adding a huge time delay for getting into the app.

Is this intentional or perhaps a bug that was fixed recently? I think we are using a rather old version of this library. I believe beta2.

Comments (43)

  1. Martin Felis repo owner

    In jni/love/src/love.cpp you can remove these lines at the bottom of the main function.

    #ifdef LOVE_ANDROID
        exit(retval);
    #endif
    

    Does that fix your problem?

    I would highly recommend you to update to the latest version in the git repository as it also fixes a nasty battery drain bug (see #83 for details).

  2. Karthik T reporter

    Thanks! Sounds like the culprit! As for the version, just checked against your repo, looks like we are on .91a, we got the commit just before the README was updated to show that hence I assumed beta :P

  3. Karthik T reporter

    Hey, Yup thats the one.. Its brilliant now. Is there any reason for that block? Anything that I will miss? or get burned by?

  4. Karthik T reporter

    Hey is it buildable for you? Am getting make: *** No rule to make target `jni/openal-soft-android/Alc/backends/base.c', needed by `obj/local/armeabi/objs/openal/Alc/backends/base.o'. Stop

  5. Martin Felis repo owner

    Run ndk-build clean. It lets you start the build process anew.

    The block is in there as I found it to be the only way to actually close the app. Not nice but could not yet find another workaround.

  6. Karthik T reporter

    Ah yes silly me.. clean fixed the compile error. As for closing the app, isnt just closing the activity enough? That should be more androidish and i believe the code already does that.

  7. Karthik T reporter

    By commenting this out I cannot restart the engine anymore.. It crashes.. I guess somewhere there are unreleased resources?

  8. Martin Felis repo owner

    I guess that was the reason I kept it after all. I think the problem is somewhere in the Java-C wrapping code. I have just updated to the latest SDL2 and also removed the exit(retval); statement. So quitting the App should now do the things as intended from SDL2 (i.e. without hacks from me).

    Can you give it a shot and tell me whether it works in a way you would expect it?

  9. Karthik T reporter

    After updating SDLActivity, I am getting this on the 2nd play though

    10-23 14:00:05.677  <package>   7451    7691    E   AndroidRuntime  FATAL EXCEPTION: SDLThread
    10-23 14:00:05.677  <package>   7451    7691    E   AndroidRuntime  Process: com.samsung.carnival, PID: 7451
    10-23 14:00:05.677  <package>   7451    7691    E   AndroidRuntime  java.lang.NullPointerException
    10-23 14:00:05.677  <package>   7451    7691    E   AndroidRuntime  at org.libsdl.app.SDLMain.run(SDLActivity.java:833)
    10-23 14:00:05.677  <package>   7451    7691    E   AndroidRuntime  at java.lang.Thread.run(Thread.java:841)
    
  10. Karthik T reporter

    I noticed something weird.. possibly because of 2 different instances of SDLActivity

    10-23 14:11:07.762  <package>   8194    8194    V   SDL         onCreate():org.love2d.android.GameActivity@42b86e70
    10-23 14:11:07.777  <package>   8194    8194    D   SDL         Initialize called [KT]
    10-23 14:11:07.777  <package>   8194    8194    D   SDL         Singleton Set [KT]
    10-23 14:11:07.777  <package>   8194    8194    V   SDL         onResume()
    10-23 14:11:07.797  <package>   8194    8194    V   SDL         onDestroy()
    10-23 14:11:07.797  <package>   8194    8194    D   SDL         Initialize called [KT]
    10-23 14:11:07.807  <package>   8194    8194    D   GAME ACTIVITY   Switching to tab - WIN_PRIZES
    10-23 14:11:07.907  <package>   8194    8194    V   SDL         surfaceCreated()
    10-23 14:11:07.907  <package>   8194    8194    V   SDL         surfaceChanged()
    10-23 14:11:07.907  <package>   8194    8194    V   SDL         pixel format RGB_565
    10-23 14:11:07.907  <package>   8194    8194    V   SDL         Window size:480x800
    

    The [KT] are my own logs. Seems like a onDestroy is getting called when it shouldnt

  11. Karthik T reporter

    I added a check in the bottom of the onDestroy. Now I can get into my 2nd play.. but very oddly cant seem to get out. My game calls love.quit and then the logs indicate that it is freed and everything, but it is still on the screen and unresponsive.. Doesnt happen all the time though..

    if (SDLActivity.mSingleton == this){
                SDLActivity.initialize();
            }
    
  12. Karthik T reporter

    I figured out the cause of both the issues.. onDestroy is heavily delayed.. like 5-10 seconds. If i restart the engine within that, either it crashes, or after my check, doesnt go back to the app. If i wait for the onDestroy and then start again, it works.

    It appears to go into OnPause first, and 10 seconds later, OnDestroy

    10-23 15:07:17.997  <package>   16155   16748   I   SDL/APP     freeing memory for in-memory game.love
    10-23 15:07:18.017  <package>   16155   16155   V   SDL         onPause()
    10-23 15:07:18.017  <package>   16155   16155   V   SDL         nativePause()
    
  13. Martin Felis repo owner

    Wow, thanks for digging so deep!

    Android gives no guarantees when onDestroy() gets called. In SDLActivity.java you can try to run mSingleton.initialize() in handleNativeExit() (either before or after the finish() call). I would be very thankful if you could give it a try.

  14. Karthik T reporter

    I can give it a shot. The odd part is, I tried the old code before the latest set of fixes, and the issue cant be reproduced.. I hate temperamental bugs.. Let me get this working anyway, probably a better fix

  15. Karthik T reporter

    Nope, behaves the same as my fix, If i restart before onDestroy fires, it still hangs at the end, even after moving the initialize. The reason I can see it clearly is that I have other app level stuff happening in onDestroy which let me see when it fires

  16. Martin Felis repo owner

    At least that I can explain: the old version caused a crash of the App by exiting LÖVE's main function with the exit(retval); call. Somehow this does not cause an App error and therefore it seems as if the app just ended properly. If you then start the app again it starts from a completely new environment whereas now the initialization is likely to not do stuff properly.

  17. Karthik T reporter

    When I said old there I mean from 2 days ago. Pre current issues, but I believe containing the commented out exit. Actually I think it is all the exact same problem. The timing of onDestroy. Along with the old code working, the old code had prompt onDestroys as well.

    Btw current issue.. I notice you set mExitCalledFromJava in onDestroy and then immediately wipe it in initialize. I wonder if that or anything similar might be causing a deadlock like situation with a second activity starting before the first has fully onDestroyed. I was trying to move the code in onDestroy as well to handleNativeQuit when I noticed this.. Not sure now should i call destroy -> initialize or how.

  18. Karthik T reporter

    Hmm.. Seems to work now.. Kept the initialize in the bottom of onDestroy, renamed it to destroy, and called destroy in handleNativeQuit. But unfortunately I guess the thread tear down or whatever now adds a second or so to the exit time. And it seems that onDestroy itself is more prompt now.. i dont know... ...

  19. Martin Felis repo owner

    Note: I wrote that before I read your last post

    I am not sure. The code of SDLActivity.java is apart from loading of the shared libraries the code of SDL2.

    From my reasoning mExitCalledFromJava is used to ensure that SDLActivity.initialize() is only called once as onDestroy() will send the quit event to the native SDL2 code, which will quit and end up in the finally { ... } segment where the actual SDL2 thread is being created (somewhere in surfaceChanged().

    Are you running the Engine using an Intent? Maybe you can call it with using a singleTask or singleInstance mode?

  20. Karthik T reporter

    We are still using intent and not singleTask or singleInstance. I think ill stick with my fix for now, unless you foresee any issues? I just hope the delay isnt too noticable..

  21. Karthik T reporter

    Thanks a lot for your patience and prompt responses man, hope I dont have to bother you yet again :)

  22. Karthik T reporter

    Spoke too soon :(

    My fix seems to have 2 issues.

    1) onPause might happen after handleNativeQuit and this was causing NPE for mSurface
    2) I got out of memory exceptions after 3-4 restarts..

    Will need to look deeper into this tomorrow. I am tempted just to go back to the exit() stage..

  23. Karthik T reporter

    3) Oddest of the lot. Even though getGamePath is right, once you load game A, every time after that seems to only load game A, regardless of which game you try to load. i.e getGamePath correctly points to game B, but Love loads game A

    10-27 16:31:46.850  20830-20830/<package> D/GameActivity﹕ Selected the file: /storage/emulated/0/Android/data/<package>/files/clowns_as_many-0f87f47b44c6ec32aa94323c05ab351c94703d2b.love
    10-27 16:31:47.014  20830-21515/<package> I/SDL/APP﹕ Trying to mount /storage/emulated/0/Android/data/<package>/files/clowns-9a5a02aa53c135d05525e54a81c05c28a6f6c3be.love
    
  24. Martin Felis repo owner

    It is all related to each other: The SDLActivity instance is not properly cleaned up or the native code still talks to the old instance instead of the new one and therefore gets the old game path. See also #66.

    Maybe it is possible in a OnNewIntent call to tell the old instance to end the native code, clean up and reinitialize. That would be uber! I would love to be able to fix this.

  25. Karthik T reporter

    Odd thing is the getGamePath is static.. so not sure

    I have actually kinda given up :( Under deadline pressure, so for now, I reverted to the pre SDL 2 version with the app quit, and gonna hack something there if possible. I will try to return to this in the next version of the app.

  26. Karthik T reporter

    The other odd thing is the timing. It is very odd that onPause happens after the new instance is started. I wonder if it is just timing issue, or if something else is causing it to specifically happen this way..

  27. Martin Felis repo owner

    The current version properly quits without calling exit(retval); and can be restarted. Would be great if you could confirm it otherwise I will close this ticket soonish.

  28. Karthik T reporter

    Great to hear this! Deadlines are real tight now, Ill keep this in mind and try this when i get some breathing room..

  29. Karthik T reporter

    Could you point me to the commit(s) which fixed this? Or was this an upstream fix? Im curious

  30. Karthik T reporter

    Just tried it. Multiple games CANNOT be run, It keeps running the first one. It does exit immediately atleast

  31. Martin Felis repo owner

    Yes, but that is a different issue (but which was also discussed here). I have created a new issue concerning running multiple .love files here: #104.

  32. Martin Felis repo owner

    There certainly is an improvement as quitting the game is now working properly and does not result in a crash when restarting the app. From my point of view this is what this issue is primarily about.

    The secondary issue of not being able to start a new game still persists, I agree. That is why I created #104 (a duplicate of #66) to separate the individual issues.

    As I understand this secondary issue is what you refer to as "not very different from where I was earlier". Am I correct or do I miss something?

  33. Karthik T reporter

    I meant that when I gave up debugging this issue, I already had it working without crashes and was able to restart it fine, only thing left was the secondary issue as you put it. Thus this fix is not very different from where I left off. Although I would consider the secondary issue a bug in the primary issue of "able to restart"

  34. Karthik T reporter

    There is one occasional crash now, if I open and close often, sometimes it crashes on this line.

    */

    class SDLMain implements Runnable {
        @Override
        public void run() {
            // Runs SDL_main()
            SDLActivity.nativeInit(SDLActivity.mSingleton.getArguments());
    
            //Log.v("SDL", "SDL thread terminated");
        }
    }
    

    Any ideas? Should I make this a seperate ticket?

  35. Karthik T reporter

    Since you are now using a static activity, I commented out // mSingleton = null; . Does this seem reasonable? I am thinking this should prevent the NPE

  36. Log in to comment