We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2297

Summary: Erroneously Receiving SDL_APP_TERMINATING Event on Configuration Change
Product: SDL Reporter: Joe LeVeque <joeleveque>
Component: *don't know*Assignee: Gabriel Jacobo <gabomdq>
Status: RESOLVED INVALID QA Contact: Sam Lantinga <slouken>
Severity: major    
Priority: P2    
Version: HG 2.1   
Hardware: ARM   
OS: Android (All)   
Attachments: SDLActivity.java patch to prevent SDL_APP_TERMINATING event on configuration change

Description Joe LeVeque 2013-12-11 18:21:47 UTC
I have an Android app that runs in landscape mode. While the app is running, if I press the 'Home' key, the app gets sent to the background and I receive the SDL_APP_WILLENTERBACKGROUND/SDL_APP_DIDENTERBACKGROUND events properly. Once the app is brought back to the foreground, I receive the SDL_APP_WILLENTERFOREGROUND/SDL_APP_DIDENTERFOREGROUND events and I am able to resume my app properly.

However, if the app is in the foreground when the device goes to sleep (either due to timeout or power button press), I receive the WILLENTERBACKGROUND/SDL_APP_DIDENTERBACKGROUND events followed immediately by a SDL_APP_TERMINATING event. After doing some research, I believe onDestroy() gets called when the configuration changes (i.e. landscape->portrait and vice-versa). This, however is not necessarily an indicator that the OS is killing the app, but only that it is destroying the current configuration. As I don't want my app to ever change configurations, my first idea at a workaround was to simply ignore the SDL_APP_TERMINATING event, but then my application would hang, due to the SDLActivity.mSDLThread.join() in onDestroy().

After more research, I found that Android Activities provide an isFinishing() function that can be used to determine whether the Activity is actually being terminated. I found that using this in onDestroy() prevents the SDL app from receiving an erroneous SDL_APP_TERMINATING event. However, I haven't figured out how to force a situation where Android sends an actual termination event in order to test that it works properly in that instance as well.

Attached is my patch.
Comment 1 Joe LeVeque 2013-12-11 18:23:19 UTC
Created attachment 1494 [details]
SDLActivity.java patch to prevent SDL_APP_TERMINATING event on configuration change
Comment 2 Joe LeVeque 2013-12-11 20:33:41 UTC
Related documentation:

http://developer.android.com/reference/android/app/Activity.html#onDestroy()

http://developer.android.com/reference/android/app/Activity.html#isFinishing()

Also looks like isFinishing() is commonly used in onPause() to serve the same function:

http://developer.android.com/reference/android/app/Activity.html#onPause()
Comment 3 Gabriel Jacobo 2013-12-12 12:07:50 UTC
Do you have android:configChanges="orientation" in your AndroidManifest.xml ?
Comment 4 Joe LeVeque 2013-12-13 18:21:42 UTC
I did not, because it never worked in the past, but after some research and trial-and-error I think I might have figured it out. Here's a long-winded explanation for posterity's sake:

I had originally tried using:

android:screenOrientation="landscape"
android:configChanges="orientation" 

in AndroidManifest.xml to achieve what I wanted, but it never worked, so I had instead tried doing it programatically by calling:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

in Java. This appeared to do what I wanted, so I left it alone. However, using this method apparently causes Android not to call onConfigurationChanged() when configuration changes occur, but I guess it still calls onDestroy()?? I'm still not quite clear on what the actual behavior is/should be here.

Anyway, after some research, I think I found the reason why android:configChanges="orientation" never worked. According to the Android documentation (http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange), beginning with Android 3.2, the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change, you must declare android:configChanges="orientation|screenSize".

After making this change, I now see that my overridden onConfigurationChanged() is being called, and onDestroy() is apparently no longer being called, thus I am no longer receiving the SDL_APP_TERMINATING event, and the configuration change seems to go get ignored as intended.
Comment 5 Gabriel Jacobo 2013-12-13 20:59:54 UTC
Ok, thanks for the report!