The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Android onResume not called? Should it be called?
Michael Labbe
Guest

I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe
Android onResume not called? Should it be called?
Owen Alanzo Hogarth
Guest

can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:
Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Michael Labbe
Guest

My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Martin Gerhardy
Guest

How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:

Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe <[url=mailto:][/url]> wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
--
--

http://www.caveproductions.org
http://www.ufoai.org
Android onResume not called? Should it be called?
Owen Alanzo Hogarth
Guest

Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Michael Labbe
Guest

Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Jonny D


Joined: 12 Sep 2009
Posts: 932
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Michael Labbe
Guest

So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Jonny D


Joined: 12 Sep 2009
Posts: 932
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Michael Labbe
Guest

Unfortunately, you can't trap quit if the thread is being killed while the app is in the background, as I have seen evidence of.  I can't reproduce it, but I know for sure that I have seen this multiple times within the last day or so by using other apps and then attempting to return to the app via the task manager.  So, there is no way of resetting global and static state on exit because the thread is being inexplicably killed by the OS.

Compounding this problem is a question of what is actually initialized when main() opens a second time.  Even SDL initialization is in a limbo state.  For example: SDL_CreateWindow() fails with SDL_GetError() returning that only one Android window can exist at a time, but SDL_GL_CreateContext() must be called or else every GL call crashes (at least on a tegra GPU, who knows about others).


So, while a lot of global state is still set on reentry into main(), there is a bunch of it that is invalid.  And there are no hard, fast rules as to which is which.


I imagine all of the JNI related functions are now invalid as I am using weak global references and SDLThread has exited.  But I will have to test each and every case and see what crashes and hope that this matches across 1000+ android devices and fifteen operating system versions.


Or am I completely in the weeds here and there is a better way to do all of this?


On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Daniel Gibson
Guest

On 09/24/2015 04:08 AM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.
It's a platform issue because the Java side loads your native code as a
dynamic library and never unloads it (and I don't think any API to
unload it exists on Android). So when the Java code calls into your

I think in normal Java people sometimes use two native dynamic libs as a
workaround: One with the actual logic (in this case sdl.so or something)
and a second that loads/unloads the first one (with native
dlopen()/dlclose()) and probably also needs to wrap the whole API.
So the Java code only opens the second one.
I guess this should work for Android as well?

Quote:
main() a second time, the static (and global?) variables are already set.

You can avoid an Android-only code section with a custom generic quit()
that resets your static variables to their initial values.

Jonny D



On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe
<mailto:> wrote:

So, what we're saying is that it's possible and reasonable, on
Android, to have the SDLThread be killed while the app is in the
background, and to have it call main() a second time if the app is
re-opened?

That's completely unlike any of the other platforms SDL2 supports
and supporting that seems like a very strange requirement. It
breaks the main() metaphor entirely.

Just making absolutely sure I am not putting an unnecessary
android-specific piece of code in to skip all subsystem and engine
initialization the second time it goes through main and that this is
intended by design?


This is definitely happening on a wide-ish range of Android devices
in our testing, by the way. We are seeing re-entry crashes (thanks
to Crashlytics) on Android major version 4 and 5 and across device
brands.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Android onResume not called? Should it be called?
Owen Alanzo Hogarth
Guest

Hi guys

I was working on this issue recently. I wanted to turn SDL android into a live wallpaper type app and I continually ran into these types of crashes.

What I was able to do instead of using static variables and loading sdl .so statically, I basically removed most of the static variables from sdl activity and the main class. This seems to be working just fine for the regular app as well as mostly working fine for the live wallpaper implementation.

Once I get it sorted out properly I will submit a patch that should take care of all these issues.


Also I noticed the class SDLAndroid_touch.c was calling into the JNI env and getting some static variables. I think this might not be such a great idea. I also removed that code and just replaced it with a function that returns a true or false from SDL_android.c


This way any code that actually deals with JNI is in SDL_android.c and I think that would keep thing simpler to maintain.


I could post up some of the code if anyone would like to see it, although it still need to be cleaned up since I was doing some madness with JNI to see how I could make the SDLActivity.java use non static variables.


On Thu, Sep 24, 2015 at 10:32 AM, Daniel Gibson wrote:
Quote:
On 09/24/2015 04:08 AM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.
It's a platform issue because the Java side loads your native code as a
dynamic library and never unloads it (and I don't think any API to
unload it exists on Android).  So when the Java code calls into your

I think in normal Java people sometimes use two native dynamic libs as a workaround: One with the actual logic (in this case sdl.so or something) and a second that loads/unloads the first one (with native dlopen()/dlclose()) and probably also needs to wrap the whole API.
So the Java code only opens the second one.
I guess this should work for Android as well?

Quote:
main() a second time, the static (and global?) variables are already set.

You can avoid an Android-only code section with a custom generic quit()
that resets your static variables to their initial values.

Jonny D



On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe
<mailto:> wrote:

    So, what we're saying is that it's possible and reasonable, on
    Android, to have the SDLThread be killed while the app is in the
    background, and to have it call main() a second time if the app is
    re-opened?

    That's completely unlike any of the other platforms SDL2 supports
    and supporting that seems like a very strange requirement.  It
    breaks the main() metaphor entirely.

    Just making absolutely sure I am not putting an unnecessary
    android-specific piece of code in to skip all subsystem and engine
    initialization the second time it goes through main and that this is
    intended by design?


    This is definitely happening on a wide-ish range of Android devices
    in our testing, by the way. We are seeing re-entry crashes (thanks
    to Crashlytics) on Android major version 4 and 5 and across device
    brands.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Android onResume not called? Should it be called?
Owen Alanzo Hogarth
Guest

More specifically.


You can actually test for this bug pretty easily on android.

When your app launches do a check to see if the mSDLthread == null


When the app launches cleanly that check will be true and your app will launch without a problem.


Sometimes though that check will be false and that's when you get your crashes.


On Thu, Sep 24, 2015 at 11:31 AM, Owen Alanzo Hogarth wrote:
Quote:
Hi guys

I was working on this issue recently. I wanted to turn SDL android into a live wallpaper type app and I continually ran into these types of crashes.

What I was able to do instead of using static variables and loading sdl .so statically, I basically removed most of the static variables from sdl activity and the main class. This seems to be working just fine for the regular app as well as mostly working fine for the live wallpaper implementation.

Once I get it sorted out properly I will submit a patch that should take care of all these issues.


Also I noticed the class SDLAndroid_touch.c was calling into the JNI env and getting some static variables. I think this might not be such a great idea. I also removed that code and just replaced it with a function that returns a true or false from SDL_android.c


This way any code that actually deals with JNI is in SDL_android.c and I think that would keep thing simpler to maintain.


I could post up some of the code if anyone would like to see it, although it still need to be cleaned up since I was doing some madness with JNI to see how I could make the SDLActivity.java use non static variables.


On Thu, Sep 24, 2015 at 10:32 AM, Daniel Gibson wrote:
Quote:
On 09/24/2015 04:08 AM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.
It's a platform issue because the Java side loads your native code as a
dynamic library and never unloads it (and I don't think any API to
unload it exists on Android).  So when the Java code calls into your

I think in normal Java people sometimes use two native dynamic libs as a workaround: One with the actual logic (in this case sdl.so or something) and a second that loads/unloads the first one (with native dlopen()/dlclose()) and probably also needs to wrap the whole API.
So the Java code only opens the second one.
I guess this should work for Android as well?

Quote:
main() a second time, the static (and global?) variables are already set.

You can avoid an Android-only code section with a custom generic quit()
that resets your static variables to their initial values.

Jonny D



On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe
<mailto:> wrote:

    So, what we're saying is that it's possible and reasonable, on
    Android, to have the SDLThread be killed while the app is in the
    background, and to have it call main() a second time if the app is
    re-opened?

    That's completely unlike any of the other platforms SDL2 supports
    and supporting that seems like a very strange requirement.  It
    breaks the main() metaphor entirely.

    Just making absolutely sure I am not putting an unnecessary
    android-specific piece of code in to skip all subsystem and engine
    initialization the second time it goes through main and that this is
    intended by design?


    This is definitely happening on a wide-ish range of Android devices
    in our testing, by the way. We are seeing re-entry crashes (thanks
    to Crashlytics) on Android major version 4 and 5 and across device
    brands.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







Android onResume not called? Should it be called?
slvn


Joined: 06 Oct 2012
Posts: 88
Maybe be this issue of already used variables can be solved by adding in the file "AndroidManifest.xml", in the "activity" markup, the following attributes:

  android:launchMode="singleInstance"
  android:alwaysRetainTaskState="true"


(Maybe you changed the "targetSdkVersion" ?)






On 24 September 2015 at 05:36, Owen Alanzo Hogarth wrote:
Quote:
More specifically.


You can actually test for this bug pretty easily on android.

When your app launches do a check to see if the mSDLthread == null


When the app launches cleanly that check will be true and your app will launch without a problem.


Sometimes though that check will be false and that's when you get your crashes.


On Thu, Sep 24, 2015 at 11:31 AM, Owen Alanzo Hogarth wrote:
Quote:
Hi guys

I was working on this issue recently. I wanted to turn SDL android into a live wallpaper type app and I continually ran into these types of crashes.

What I was able to do instead of using static variables and loading sdl .so statically, I basically removed most of the static variables from sdl activity and the main class. This seems to be working just fine for the regular app as well as mostly working fine for the live wallpaper implementation.

Once I get it sorted out properly I will submit a patch that should take care of all these issues.


Also I noticed the class SDLAndroid_touch.c was calling into the JNI env and getting some static variables. I think this might not be such a great idea. I also removed that code and just replaced it with a function that returns a true or false from SDL_android.c


This way any code that actually deals with JNI is in SDL_android.c and I think that would keep thing simpler to maintain.


I could post up some of the code if anyone would like to see it, although it still need to be cleaned up since I was doing some madness with JNI to see how I could make the SDLActivity.java use non static variables.


On Thu, Sep 24, 2015 at 10:32 AM, Daniel Gibson wrote:
Quote:
On 09/24/2015 04:08 AM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.
It's a platform issue because the Java side loads your native code as a
dynamic library and never unloads it (and I don't think any API to
unload it exists on Android).  So when the Java code calls into your

I think in normal Java people sometimes use two native dynamic libs as a workaround: One with the actual logic (in this case sdl.so or something) and a second that loads/unloads the first one (with native dlopen()/dlclose()) and probably also needs to wrap the whole API.
So the Java code only opens the second one.
I guess this should work for Android as well?

Quote:
main() a second time, the static (and global?) variables are already set.

You can avoid an Android-only code section with a custom generic quit()
that resets your static variables to their initial values.

Jonny D



On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe
<mailto:> wrote:

    So, what we're saying is that it's possible and reasonable, on
    Android, to have the SDLThread be killed while the app is in the
    background, and to have it call main() a second time if the app is
    re-opened?

    That's completely unlike any of the other platforms SDL2 supports
    and supporting that seems like a very strange requirement.  It
    breaks the main() metaphor entirely.

    Just making absolutely sure I am not putting an unnecessary
    android-specific piece of code in to skip all subsystem and engine
    initialization the second time it goes through main and that this is
    intended by design?


    This is definitely happening on a wide-ish range of Android devices
    in our testing, by the way. We are seeing re-entry crashes (thanks
    to Crashlytics) on Android major version 4 and 5 and across device
    brands.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org













_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




--
Sylvain Becker
Android onResume not called? Should it be called?
Michael Labbe
Guest

Thread resurrect.

Okay, so we know that main() can be called multiple times on Android, and that the global variables in the game's shared object are still set.  However, in order to debug this situation, it is important to be able to create the situation on the fly.


How do I force my application to be backgrounded in such a way that the activity is destroyed so that I can re-enter through main()?






On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
Owen Alanzo Hogarth
Guest

I ran into something similar when trying to have this current version of sdl work as a live wallpaper which can have up to 2 instances of the engine running at once.

To me it seems that the way android works just causes some issues with SDL.


I've personally seen that if you open android multitasking window and swipe away your sdl app, it dies but the last call you get is the onpause. None of the other sdl calls are made, such as entering background, etc.


There are other ways to kill the sdl activity on android that could cause sdl to act in undefined manner when the app is relaunched.


as it stands sdl works on android but there seems to be a lot of edge cases that needs to be tested. What you are describing is one of them.


I don't actually think there's a lot of android developers on this list although I could be mistaken but most of my android specific questions go unanswered.


On Fri, Oct 9, 2015 at 9:11 AM, Michael Labbe wrote:
Quote:
Thread resurrect.

Okay, so we know that main() can be called multiple times on Android, and that the global variables in the game's shared object are still set.  However, in order to debug this situation, it is important to be able to create the situation on the fly.


How do I force my application to be backgrounded in such a way that the activity is destroyed so that I can re-enter through main()?






On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Android onResume not called? Should it be called?
M. Gerhardy
Guest

Collecting some code lines how it works for me:

Quit command that is called from the UI or in-game console:
https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/commands/CmdQuit.h#L9

Fires a SDL_QUIT event

https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/SDLBackend.cpp#L98

The SDL_QUIT event is forwarded to some system specific implementation.


On Android this looks like this:
https://github.com/mgerhardy/caveexpress/blob/master/src/modules/common/ports/Android.cpp#L503

And the java side for this is:
https://github.com/mgerhardy/caveexpress/blob/master/android-project/src/org/base/BaseActivity.java#L236


This will pause the app via SDL events (halting the main loop).


You should never call exit.


Hope that helps.





On Fri, Oct 9, 2015 at 2:21 PM, Owen Alanzo Hogarth wrote:
Quote:
I ran into something similar when trying to have this current version of sdl work as a live wallpaper which can have up to 2 instances of the engine running at once.

To me it seems that the way android works just causes some issues with SDL.


I've personally seen that if you open android multitasking window and swipe away your sdl app, it dies but the last call you get is the onpause. None of the other sdl calls are made, such as entering background, etc.


There are other ways to kill the sdl activity on android that could cause sdl to act in undefined manner when the app is relaunched.


as it stands sdl works on android but there seems to be a lot of edge cases that needs to be tested. What you are describing is one of them.


I don't actually think there's a lot of android developers on this list although I could be mistaken but most of my android specific questions go unanswered.


On Fri, Oct 9, 2015 at 9:11 AM, Michael Labbe wrote:
Quote:
Thread resurrect.

Okay, so we know that main() can be called multiple times on Android, and that the global variables in the game's shared object are still set.  However, in order to debug this situation, it is important to be able to create the situation on the fly.


How do I force my application to be backgrounded in such a way that the activity is destroyed so that I can re-enter through main()?






On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




--
http://www.caveproductions.org
Android onResume not called? Should it be called?
Michael Labbé
Guest

Careful. You are calling CallStaticBooleanMethod on a function that returns void. This should be CallStaticVoidMethod.
While it is non-standard to call exit(), not calling exit() and letting the program flow out of main() ensures that it will re-launch through main with all of your globals set. So, I am self-answering my earlier question: that is how to reproduce the bug — let the program flow out of main().

While it would be nice not to have global state, sometimes you are tasked with porting a codebase that has globals.

I am working on implementing a proxy .so library that calls the game .so with dlopen() and dlclose(), ensuring the data segment is zeroed. I will report back.
Michael Labbé
Quote:
On Oct 9, 2015, at 7:57 AM, M. Gerhardy wrote:
Collecting some code lines how it works for me:Quit command that is called from the UI or in-game console:https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/commands/CmdQuit.h#L9
Fires a SDL_QUIT eventhttps://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/SDLBackend.cpp#L98
The SDL_QUIT event is forwarded to some system specific implementation.
On Android this looks like this:https://github.com/mgerhardy/caveexpress/blob/master/src/modules/common/ports/Android.cpp#L503And the java side for this is:https://github.com/mgerhardy/caveexpress/blob/master/android-project/src/org/base/BaseActivity.java#L236
This will pause the app via SDL events (halting the main loop).
You should never call exit.
Hope that helps.


On Fri, Oct 9, 2015 at 2:21 PM, Owen Alanzo Hogarth wrote:
Quote:
I ran into something similar when trying to have this current version of sdl work as a live wallpaper which can have up to 2 instances of the engine running at once.
To me it seems that the way android works just causes some issues with SDL.

I've personally seen that if you open android multitasking window and swipe away your sdl app, it dies but the last call you get is the onpause. None of the other sdl calls are made, such as entering background, etc.

There are other ways to kill the sdl activity on android that could cause sdl to act in undefined manner when the app is relaunched.

as it stands sdl works on android but there seems to be a lot of edge cases that needs to be tested. What you are describing is one of them.

I don't actually think there's a lot of android developers on this list although I could be mistaken but most of my android specific questions go unanswered.

On Fri, Oct 9, 2015 at 9:11 AM, Michael Labbe wrote:
Quote:
Thread resurrect.
Okay, so we know that main() can be called multiple times on Android, and that the global variables in the game's shared object are still set. However, in order to debug this situation, it is important to be able to create the situation on the fly.

How do I force my application to be backgrounded in such a way that the activity is destroyed so that I can re-enter through main()?



On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate. It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android). So when the Java code calls into your main() a second time, the static (and global?) variables are already set.

You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.

Jonny D



On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?
That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement. It breaks the main() metaphor entirely.

Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?


This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.

On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason. I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values. You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.
Jonny D


On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.
Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground). It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.

My key question remains:

Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?

On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.

void handle_event(SDL_Event* e)
{
if (e->type == SDL_KEYDOWN)
if (e->key.keysym.sym == SDLK_AC_BACK )
{
do your quitting code here
}
.......

I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.

On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application? Am 21.09.2015 um 10:33 schrieb Michael Labbe:


Quote:
My event handling code calls this at startup:
SDL_SetEventFilter(HandleAppEvents, NULL);

And then, HandleAppEvents returns 0 (handles and eats the event for):
- SDL_APP_TERMINATING
- SDL_APP_DIDENTERBACKGROUND
- SDL_APP_DIDENTERFOREGROUND

It does not explictly handle, and returns 1, for all other events.

... but regardless, why is main() being called twice in one launch of the app? Once at startup, and once on resume from background.

On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?
On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:

Quote:
I'm dealing with my app being loaded from the background. The vast majority of the time, onResume is called. I catch that event and deal with it in native code. Great -- everything's fine.

Sometimes, onResume is not called and I end up in my main() function. However, all of my globals are still initialized, so the application state seems to be present.

I have partial repro steps on this by:
- launching my game
- pressing the home button
- tapping my game's icon
- since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.

I'm using 2.0.4RC1.
What is Android doing here?
Michael Labbe




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org



_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

-- http://www.caveproductions.org



_______________________________________________SDL mailing://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Android onResume not called? Should it be called?
Michael Labbe
Guest

Okay, I can confirm this works -- you can avoid re-entries into main() that have global variables initialized.  I'm in the throes of finalling a game right now and I don't have time to parcel out a clean version of this, but here's how it works:

 1. Compile libSDL2.so. It must be a shared library.  Compile your game library.  It must also be a shared library that does not statically link with SDL2.
 2. Create another shared library, called a proxy.
 3. Set both the proxy and SDL to load in loadLibrary in SDLActivity.  Do not put the game library in there.
 4. Set SDLActivity to call a function called "proxyInit" instead of "nativeInit.".
 5. Have the proxy library's proxyInit code perform all of the same startup routines as nativeInit does for SDL.
      - dlopen libSDL2.so to call SDL_Android_Init() and SDL_SetMainReady()
 6. In your game, rename main() to game_main().
 7. dlopen your game shared object library and call game_main()
 8. when it finishes, dlclose() your game shared object library. This should be the only handle to it so it is purged from memory.


Make sure you don't call exit() at the end of game_main().


Hopefully once I ship I have some time to share reusable code. 


On Fri, Oct 9, 2015 at 10:05 AM, Michael Labbé wrote:
Quote:
Careful.  You are calling CallStaticBooleanMethod on a function that returns void.  This should be CallStaticVoidMethod.

While it is non-standard to call exit(), not calling exit() and letting the program flow out of main() ensures that it will re-launch through main with all of your globals set.  So, I am self-answering my earlier question: that is how to reproduce the bug — let the program flow out of main().


While it would be nice not to have global state, sometimes you are tasked with porting a codebase that has globals.


I am working on implementing a proxy .so library that calls the game .so with dlopen() and dlclose(), ensuring the data segment is zeroed.  I will report back.

Michael Labbé

Quote:
On Oct 9, 2015, at 7:57 AM, M. Gerhardy wrote:

Collecting some code lines how it works for me:

Quit command that is called from the UI or in-game console:
https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/commands/CmdQuit.h#L9

Fires a SDL_QUIT event

https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/SDLBackend.cpp#L98

The SDL_QUIT event is forwarded to some system specific implementation.


On Android this looks like this:
https://github.com/mgerhardy/caveexpress/blob/master/src/modules/common/ports/Android.cpp#L503

And the java side for this is:
https://github.com/mgerhardy/caveexpress/blob/master/android-project/src/org/base/BaseActivity.java#L236


This will pause the app via SDL events (halting the main loop).


You should never call exit.


Hope that helps.





On Fri, Oct 9, 2015 at 2:21 PM, Owen Alanzo Hogarth wrote:
Quote:
I ran into something similar when trying to have this current version of sdl work as a live wallpaper which can have up to 2 instances of the engine running at once.

To me it seems that the way android works just causes some issues with SDL.


I've personally seen that if you open android multitasking window and swipe away your sdl app, it dies but the last call you get is the onpause. None of the other sdl calls are made, such as entering background, etc.


There are other ways to kill the sdl activity on android that could cause sdl to act in undefined manner when the app is relaunched.


as it stands sdl works on android but there seems to be a lot of edge cases that needs to be tested. What you are describing is one of them.


I don't actually think there's a lot of android developers on this list although I could be mistaken but most of my android specific questions go unanswered.


On Fri, Oct 9, 2015 at 9:11 AM, Michael Labbe wrote:
Quote:
Thread resurrect.

Okay, so we know that main() can be called multiple times on Android, and that the global variables in the game's shared object are still set.  However, in order to debug this situation, it is important to be able to create the situation on the fly.


How do I force my application to be backgrounded in such a way that the activity is destroyed so that I can re-enter through main()?






On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




--
http://www.caveproductions.org




_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





Android onResume not called? Should it be called?
Michael Labbe
Guest

Hey all,

Just wanted to send an email 4 days later to confirm that this proxy approach actually works.  We went from 30% of our users crashing due to problems after re-entering main right to zero.


Some other points, for the record:


 - It was mentioned elsewhere in this thread to not use SDL_SetEventFilter() to handle SDL_APP_DIDENTERFOREGROUND and SDL_APP_DIDENTERBACKGROUND.  I just wanted to clarify that these are fine and we use them without problems.


 - We do not call exit() at the end of main() anymore.  This lets Android naturally handle its lifecycle. (And it is indeed like nature -- it can be killed at any time: before onPause, after onPause but before onDestroy, after onDestroy....).


 - When you use this proxy technique, on resume, you may very well be entering through main with no native state set, so make sure you have archived your game state somewhere and can bring the user back quickly.


 - If you have other native threads running that were created with SDL_CreateThread, you need to halt them when you leave main().  I didn't look into exactly what was happening when our jobs were continuing to run after dlclose() was called, but it couldn't have been good.  Just don't do it.


 - We compiled with SDL_ANDROID_BLOCK_ON_PAUSE.


 - Using android:alwaysRetainTaskState="true" and lauching the launchMode to retain seemingly had no impact.  We tested these and reverted them.


So, there you go.  A record of an Android SDL2 game lifecycle working as you would expect (with minor mods to SDL2 as mentioned).


On Fri, Oct 9, 2015 at 1:05 PM, Michael Labbe wrote:
Quote:
Okay, I can confirm this works -- you can avoid re-entries into main() that have global variables initialized.  I'm in the throes of finalling a game right now and I don't have time to parcel out a clean version of this, but here's how it works:

 1. Compile libSDL2.so. It must be a shared library.  Compile your game library.  It must also be a shared library that does not statically link with SDL2.
 2. Create another shared library, called a proxy.
 3. Set both the proxy and SDL to load in loadLibrary in SDLActivity.  Do not put the game library in there.
 4. Set SDLActivity to call a function called "proxyInit" instead of "nativeInit.".
 5. Have the proxy library's proxyInit code perform all of the same startup routines as nativeInit does for SDL.
      - dlopen libSDL2.so to call SDL_Android_Init() and SDL_SetMainReady()
 6. In your game, rename main() to game_main().
 7. dlopen your game shared object library and call game_main()
 8. when it finishes, dlclose() your game shared object library. This should be the only handle to it so it is purged from memory.


Make sure you don't call exit() at the end of game_main().


Hopefully once I ship I have some time to share reusable code. 


On Fri, Oct 9, 2015 at 10:05 AM, Michael Labbé wrote:
Quote:
Careful.  You are calling CallStaticBooleanMethod on a function that returns void.  This should be CallStaticVoidMethod.

While it is non-standard to call exit(), not calling exit() and letting the program flow out of main() ensures that it will re-launch through main with all of your globals set.  So, I am self-answering my earlier question: that is how to reproduce the bug — let the program flow out of main().


While it would be nice not to have global state, sometimes you are tasked with porting a codebase that has globals.


I am working on implementing a proxy .so library that calls the game .so with dlopen() and dlclose(), ensuring the data segment is zeroed.  I will report back.

Michael Labbé

Quote:
On Oct 9, 2015, at 7:57 AM, M. Gerhardy wrote:

Collecting some code lines how it works for me:

Quit command that is called from the UI or in-game console:
https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/commands/CmdQuit.h#L9

Fires a SDL_QUIT event

https://github.com/mgerhardy/caveexpress/blob/master/src/modules/server/SDLBackend.cpp#L98

The SDL_QUIT event is forwarded to some system specific implementation.


On Android this looks like this:
https://github.com/mgerhardy/caveexpress/blob/master/src/modules/common/ports/Android.cpp#L503

And the java side for this is:
https://github.com/mgerhardy/caveexpress/blob/master/android-project/src/org/base/BaseActivity.java#L236


This will pause the app via SDL events (halting the main loop).


You should never call exit.


Hope that helps.





On Fri, Oct 9, 2015 at 2:21 PM, Owen Alanzo Hogarth wrote:
Quote:
I ran into something similar when trying to have this current version of sdl work as a live wallpaper which can have up to 2 instances of the engine running at once.

To me it seems that the way android works just causes some issues with SDL.


I've personally seen that if you open android multitasking window and swipe away your sdl app, it dies but the last call you get is the onpause. None of the other sdl calls are made, such as entering background, etc.


There are other ways to kill the sdl activity on android that could cause sdl to act in undefined manner when the app is relaunched.


as it stands sdl works on android but there seems to be a lot of edge cases that needs to be tested. What you are describing is one of them.


I don't actually think there's a lot of android developers on this list although I could be mistaken but most of my android specific questions go unanswered.


On Fri, Oct 9, 2015 at 9:11 AM, Michael Labbe wrote:
Quote:
Thread resurrect.

Okay, so we know that main() can be called multiple times on Android, and that the global variables in the game's shared object are still set.  However, in order to debug this situation, it is important to be able to create the situation on the fly.


How do I force my application to be backgrounded in such a way that the activity is destroyed so that I can re-enter through main()?






On Wed, Sep 23, 2015 at 7:08 PM, Jonathan Dearborn wrote:
Quote:
It indeed does break conceptions about main(), and that is unfortunate.  It's a platform issue because the Java side loads your native code as a dynamic library and never unloads it (and I don't think any API to unload it exists on Android).  So when the Java code calls into your main() a second time, the static (and global?) variables are already set.



You can avoid an Android-only code section with a custom generic quit() that resets your static variables to their initial values.


Jonny D






On Wed, Sep 23, 2015 at 9:08 PM, Michael Labbe wrote:
Quote:
So, what we're saying is that it's possible and reasonable, on Android, to have the SDLThread be killed while the app is in the background, and to have it call main() a second time if the app is re-opened?

That's completely unlike any of the other platforms SDL2 supports and supporting that seems like a very strange requirement.  It breaks the main() metaphor entirely.


Just making absolutely sure I am not putting an unnecessary android-specific piece of code in to skip all subsystem and engine initialization the second time it goes through main and that this is intended by design?




This is definitely happening on a wide-ish range of Android devices in our testing, by the way. We are seeing re-entry crashes (thanks to Crashlytics) on Android major version 4 and 5 and across device brands.


On Tue, Sep 22, 2015 at 10:10 AM, Jonathan Dearborn wrote:
Quote:
So, yes, there is a reason.  I'm not totally up on it, but Eric Wing pointed out to me that since the native code is managed by Java via .so loading, when an app resumes from the background without having its process killed, static variables may retain their old values.  You must de-initialize these before your app exits to ensure that running your initialization again will work correctly.

Jonny D




On Tue, Sep 22, 2015 at 12:55 PM, Michael Labbe wrote:
Quote:
Being able to quit the application with the back button is a given for proper UI conformance, but that doesn't solve reentry for more complicated scenarios such as returning to an app after responding to an email activity.

Also, re-entering through main() in Android is totally incongruous with iOS app delegate responder messages (ex: applicationDidEnterForeground).  It would be best to figure out why the app is re-entering in main() instead of triggering the specific event and deal with that.


My key question remains: 


Is there any reason why an Android app using SDL would enter main() more than once, but have all global variables still be initialized?


On Mon, Sep 21, 2015 at 2:43 AM, Owen Alanzo Hogarth wrote:
Quote:
Here's how i'd recommend exiting your application.


void handle_event(SDL_Event* e)
{
    if (e->type == SDL_KEYDOWN)
        if (e->key.keysym.sym == SDLK_AC_BACK )
        {
            do your quitting code here
        }
.......


I wouldn't recommend using event filters, why? I do mainly android dev and never had to use it, maybe others on this list will have different opinions though.
There was some discussion on this thread earlier about using exit(0) or some other method to break your loop instead.


On Mon, Sep 21, 2015 at 4:53 PM, Martin Gerhardy wrote:
Quote:
How do you exit your application?

Am 21.09.2015 um 10:33 schrieb Michael Labbe:



Quote:
My event handling code calls this at startup:

SDL_SetEventFilter(HandleAppEvents, NULL);



And then, HandleAppEvents returns 0 (handles and eats the event for):
 - SDL_APP_TERMINATING
 - SDL_APP_DIDENTERBACKGROUND
 - SDL_APP_DIDENTERFOREGROUND


It does not explictly handle, and returns 1, for all other events.


... but regardless, why is main() being called twice in one launch of the app?  Once at startup, and once on resume from background.


On Mon, Sep 21, 2015 at 12:58 AM, Owen Alanzo Hogarth wrote:
Quote:
can you show your event handling code?

On Mon, Sep 21, 2015 at 2:04 PM, Michael Labbe wrote:


Quote:
I'm dealing with my app being loaded from the background.  The vast majority of the time, onResume is called.  I catch that event and deal with it in native code.  Great -- everything's fine.


Sometimes, onResume is not called and I end up in my main() function.  However, all of my globals are still initialized, so the application state seems to be present.


I have partial repro steps on this by:
 - launching my game
 - pressing the home button
 - tapping my game's icon
 - since my app is now in a strange state, rerunning init code crashes it pretty quickly in my own code.


I'm using 2.0.4RC1.

What is Android doing here?


Michael Labbe





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org







_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




--
http://www.caveproductions.org




_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org








Re: Android onResume not called? Should it be called?
phobitor


Joined: 09 Jan 2015
Posts: 7
This thread is super confusing.

Can anyone confirm if I'm understanding this right:

You start your application and then it gets backgrounded. Your lifecycle callbacks look something like:
onCreate --> onStart --> onResume --> onPause (guessing this is where you get backgrounded)

Then you restore your application. Sometimes, you don't get an onResume callback. Instead, you end up back in main(). Does this mean that Android killed your application? Do you get any other callbacks in this situation like onStop, onDestroy, onCreate, onStart, etc?

When you're back in main(), global state hasn't been reset. As a work around you use a proxy lib to dlopen your game's shared lib and dlclose when leaving main()

So there are two issues
1. onResume isn't being called when it should
2. Android kills your activity but may leave the global state of its native libraries intact
phobitor


Joined: 09 Jan 2015
Posts: 7
Also a follow up thought:
Shouldn't dlclose be used on pretty much every native library to be safe? Even though global state isn't usually prevalent everywhere in a typical library it doesn't seem unlikely to see a few global variables here and there.

What do other cross platform libs like Qt do I wonder.
Android onResume not called? Should it be called?
hardcoredaniel
Guest

Hi,

if I understand things correctly, there are 2 different things to look at:

1) Android apps are being kept "loaded in memory" while they are in the background, and also when they are "terminated" (from the perspective of the user). Rationale is probably that they typically might be re-opened any time soon, so it would be wasted battery to unload them, if they are started again soon. Just guessing.
Code that uses static initialization will thus not function properly when being executed again, because static initialization only runs when code is loaded/classes are constructed. The Java side of SDL handles this by calling initialize() even in the onDestroy() callback. For your C code, you either do not use static initialization, or use the approach of Michael to load your code as library (so that static initialization runs every time you need it).

2) The "Activity Lifecycle" (http://developer.android.com/guide/components/activities.html) shows after which lifecycle callbacks an Activity can be killed. It states that any time after "onPause()" it can be killed. But it can also stay in memory after "onDestroy()". (Plus it can be killed in very rare circumstances even if not paused - but I wonder whether this can/shall be handled by an Activity, as it seems to be an "emergency situation").
There is no "main()" in Android (and as Michael stated, calling "exit()" is also not a good idea, I don't even know what it actually does on Android). So there can't be somebody magically calling "main()" for you. SDL uses a dedicated (Java) thread to call into the "main" function of the native code (look for "class SDLMain" that eventually calls "SDLActivity.nativeInit(...)", and in SDL_android_main.c finally "SDL_main" is called). But the call chain will always need to originate from a lifecycle callback, no magic.

From that theory, it should never happen that "onResume()" is not called before your app enters foreground. If your app was killed, or SDL exited "normally" (which makes the Java code forcibly run through the lifecycle until and including "onDestroy()"), then it will call "onCreate()" and "onStart()" before "onResume()". But omitting the "onResume()" should not happen.

What is probably unexpected is that upon "onCreate()" you can be in two different situations, either being "started from scratch" (with all static initializers being executed) or being "started from background" (where they won't execute again). So you must make sure that you are in a consistent state after "onDestroy()", as described earlier.

Although until now I have not seen any different behaviour of SDL on the devices I use (and gladly, I do not use static initialization in C, so I don't have to worry about library unloading), there might be devices that "misbehave", e.g. they deviate from the theory. So you can see my explanation as a theoretical one that has not been proven wrong by practice yet :-)

Regards,

Daniel


---------- Původní zpráva ----------
Od: phobitor
Komu:
Datum: 17. 10. 2015 4:22:28
Předmět: Re: [SDL] Android onResume not called? Should it be called?
Quote:
This thread is super confusing.

Can anyone confirm if I'm understanding this right:

You start your application and then it gets backgrounded. Your lifecycle callbacks look something like:
onCreate --> onStart --> onResume --> onPause (guessing this is where you get backgrounded)

Then you restore your application. Sometimes, you don't get an onResume callback. Instead, you end up back in main(). Does this mean that Android killed your application? Do you get any other callbacks in this situation like onStop, onDestroy, onCreate, onStart, etc?

When you're back in main(), global state hasn't been reset. As a work around you use a proxy lib to dlopen your game's shared lib and dlclose when leaving main()

So there are two issues
1. onResume isn't being called when it should
2. Android kills your activity but may leave the global state of its native libraries intact

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Android onResume not called? Should it be called?
marksibly


Joined: 02 Jul 2015
Posts: 14
There are some manifest settings which affect this stuff:

http://stackoverflow.com/questions/6114480/how-to-resume-android-app-where-it-was-suspended-app-not-activity




...which suggests using:
android:alwaysRetainTaskState="true"
and/or...
android:launchMode="singleInstance" //also try: "singleTask", "standard", "singleTop".


But there's also a developer setting that can apparently override this:


http://www.monkey-x.com/Community/posts.php?topic=9434&post=98174&view=all#98174







On Sat, Oct 17, 2015 at 11:04 PM, hardcoredaniel wrote:
Quote:
Hi,

if I understand things correctly, there are 2 different things to look at:

1) Android apps are being kept "loaded in memory" while they are in the background, and also when they are "terminated" (from the perspective of the user). Rationale is probably that they typically might be re-opened any time soon, so it would be wasted battery to unload them, if they are started again soon. Just guessing.
Code that uses static initialization will thus not function properly when being executed again, because static initialization only runs when code is loaded/classes are constructed. The Java side of SDL handles this by calling initialize() even in the onDestroy() callback. For your C code, you either do not use static initialization, or use the approach of Michael to load your code as library (so that static initialization runs every time you need it).

2) The "Activity Lifecycle" (http://developer.android.com/guide/components/activities.html) shows after which lifecycle callbacks an Activity can be killed. It states that any time after "onPause()" it can be killed. But it can also stay in memory after "onDestroy()". (Plus it can be killed in very rare circumstances even if not paused - but I wonder whether this can/shall be handled by an Activity, as it seems to be an "emergency situation").
There is no "main()" in Android (and as Michael stated, calling "exit()" is also not a good idea, I don't even know what it actually does on Android). So there can't be somebody magically calling "main()" for you. SDL uses a dedicated (Java) thread to call into the "main" function of the native code (look for "class SDLMain" that eventually calls "SDLActivity.nativeInit(...)", and in SDL_android_main.c finally "SDL_main" is called). But the call chain will always need to originate from a lifecycle callback, no magic.

From that theory, it should never happen that "onResume()" is not called before your app enters foreground. If your app was killed, or SDL exited "normally" (which makes the Java code forcibly run through the lifecycle until and including "onDestroy()"), then it will call "onCreate()" and "onStart()" before "onResume()". But omitting the "onResume()" should not happen.

What is probably unexpected is that upon "onCreate()" you can be in two different situations, either being "started from scratch" (with all static initializers being executed) or being "started from background" (where they won't execute again). So you must make sure that you are in a consistent state after "onDestroy()", as described earlier.

Although until now I have not seen any different behaviour of SDL on the devices I use (and gladly, I do not use static initialization in C, so I don't have to worry about library unloading), there might be devices that "misbehave", e.g. they deviate from the theory. So you can see my explanation as a theoretical one that has not been proven wrong by practice yet :-)

Regards,

Daniel


---------- Původní zpráva ----------
Od: phobitor
Komu:
Datum: 17. 10. 2015 4:22:28
Předmět: Re: [SDL] Android onResume not called? Should it be called?
Quote:
This thread is super confusing.

Can anyone confirm if I'm understanding this right:

You start your application and then it gets backgrounded. Your lifecycle callbacks look something like:
onCreate --> onStart --> onResume --> onPause (guessing this is where you get backgrounded)

Then you restore your application. Sometimes, you don't get an onResume callback. Instead, you end up back in main(). Does this mean that Android killed your application? Do you get any other callbacks in this situation like onStop, onDestroy, onCreate, onStart, etc?

When you're back in main(), global state hasn't been reset. As a work around you use a proxy lib to dlopen your game's shared lib and dlclose when leaving main()

So there are two issues
1. onResume isn't being called when it should
2. Android kills your activity but may leave the global state of its native libraries intact



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org