SDLActivity fails to finish thread in onDestroy

I’m using SDL with OpenFL, and I have a problem that I can’t solve by myself.

SDL sends exits event to native even when only Activity is destroyed (App is still alive). When the app is reopened, SDL simply restart main function without clearing previous state. This caused strange issues or crashes sometimes.

So I worked around ay preserving thread and surface after onDestroy is called, but I still have problems. SDLActivity stuck at mSDLThread.join call. I think it got stuck because no messages are printed out to log after this call.
However, SDLActivity can send SDL_Quit event correctly to native when Activity.isFinishing() returns false.
Why can’t I exit correctly when isFinishing is true?

https://developer.android.com/reference/android/app/Activity.html?hl=en#isFinishing()

The current implementation works fine for me. By declaring in the Android
manifest that all lifecycle events that would cause a onDestroy()–>onCreate
() loop with “isFinishing() == false” shall not be generated, all that is
left is onDestroy() being called explicitly when the thread that finally
calls SDL’s main() has terminated.

Independent of that, the Android app is always “still alive” after onDestroy
(), no matter whether isFinishing() is true or false. You need to handle the
fact properly that upon onCreate(), you don’t know whether you had a “fresh
start” or are resuming from a previous onDestroy().

---------- P?vodn? zpr?va ----------
Od: vroad
Komu: sdl at lists.libsdl.org
Datum: 7. 6. 2016 17:25:45
P?edm?t: [SDL] SDLActivity fails to finish thread in onDestroy

"

I’m using SDL with OpenFL, and I have a problem that I can’t solve by
myself.

SDL sends exits event to native even when only Activity is destroyed (App is
still alive). When the app is reopened, SDL simply restart main function
without clearing previous state. This caused strange issues or crashes
sometimes.

So I worked around ay preserving thread and surface after onDestroy is
called, but I still have problems. SDLActivity stuck at mSDLThread.join
call. I think it got stuck because no messages are printed out to log after
this call.
However, SDLActivity can send SDL_Quit event correctly to native when
Activity.isFinishing() returns false.
Why can’t I exit correctly when isFinishing is true?

https://developer.android.com/reference/android/app/Activity.html?hl=en#
isFinishing
(https://developer.android.com/reference/android/app/Activity.html?hl=en#isFinishing)
()_______________________________________________
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org"

It turned out that Android may kill app’s process at any time after onPause is called, even if it’s in the middle of execution, so you should save app’s state when onPause is called, or maybe you can use servlce. Service doesn’t prevent Activity from getting destroyed, but I think it will prevent process from getting killed.

I don’t think you can prevent Activity from getting destroyed by Android OS. Android may kill Activity at any time after app goes background. You can see what happens in this case by enabling “Don’t keep activities” in developer options.

Which flag are you talking about? I can prevent Activity from being destroyed when device is roated, and when software keyboard is shown, but that doesn’t solve this service.

Hi,

yes, you cannot prevent Android from killing your app. And yes, I was
referring to the entries in the manifest to disable a lifecycle event for
rotation and keyboard.

With these events disabled, I believe you will never get a onDestroy() call
from the system, only the one that SDLActivity generates itself when the C
main() function terminates. Then, Thread.join() must always succeed.

To get rid of issues when onCreate() is called but your app was not
terminated before (so some old state might have been be stored), there has
been a suggestion on this list some time ago, to put your code into a shared
library that is dlopen()ed when your C main is called, and closed (e.g.
unloaded) before your main exits.

This way, you will either be unloading your library yourself, or Android
will kill you when you are backgrounded. But there should not be any case
anymore that you suffer from states of a previous run when entering onCreate
()
?

---------- P?vodn? zpr?va ----------
Od: vroad
Komu: sdl at lists.libsdl.org
Datum: 11. 6. 2016 2:38:18
P?edm?t: Re: [SDL] SDLActivity fails to finish thread in onDestroy

"

It turned out that Android may kill app’s process at any time after onPause
is called, even if it’s in the middle of execution, so you should save app’s
state when onPause is called, or maybe you can use servlce. Service doesn’t
prevent Activity from getting destroyed, but I think it will prevent process
from getting killed.

I don’t think you can prevent Activity from getting destroyed by Android OS.
Android may kill Activity at any time after app goes background. You can see
what happens in this case by enabling “Don’t keep activities” in developer
options.

Which flag are you talking about? I can prevent Activity from being
destroyed when device is roated, and when software keyboard is shown, but
that doesn’t solve this service._______________________________________________
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org"

No, Android sometimes destroy activities without killing app’s process. As I said in previous post, you can debug this by enabling “Don’t keep activities” developer option.

Only solution I can think of is NOT destroying/stopping SDLSurface and SDLThread when onDestroy is called. If an activity is destroyed for saving memory, isFinishing returns false. Unfortunately I cannot use dlopen here, since I need to support Xamarin.Android as well. In Xamarin.Android you cannot unload assembly as it automatically loads assemblies when app is launched. And each assembly cannot be unloaded.

Hm, in that case, it seems that something is not working as expected. I see
in the Java code that when onDestroy() is called, the SDL_QUIT event is
generated. To make sure that the native side can pick it up, the native
thread is resumed in order to handle the SDL_QUIT event.

I’ll check whether I can reproduce the behaviour you describe. Meanwhile,
could it be that you are trying to do sth. in reaction to SDL_QUIT which
will not work (e.g. block) when your app is not in the foreground? That
could explain why it would only hang if the lifecycle transition is
triggered when the app is already in the background.

As you can see, I’m not in favour of keeping resources after onDestroy()? ;-
)

---------- P?vodn? zpr?va ----------
Od: vroad
Komu: sdl at lists.libsdl.org
Datum: 11. 6. 2016 12:38:27
P?edm?t: Re: [SDL] SDLActivity fails to finish thread in onDestroy

"

No, Android sometimes destroy activities without killing app’s process. As I
said in previous post, you can debug this by enabling “Don’t keep
activities” developer option.

Only solution I can think of is NOT destroying/stopping SDLSurface and
SDLThread when onDestroy is called. If an activity is destroyed for saving
memory, isFinishing returns false. Unfortunately I cannot use dlopen here,
since I need to support Xamarin.Android as well. In Xamarin.Android you
cannot unload assembly as it automatically loads assemblies when app is
launched. And each assembly cannot be unloaded._______________________________________________
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org"

Well I now think that my app was not hanging at all. When an Android app is requested to be killed, it simply dies even if it’s the middle of execution. This is what happens when you manually kills an app from recent apps or from task manager.

So problem only occurs when onDestroy is called with isFinishing() = false. This may occurs with “Don’t keep activities” in developer option, or when other apps request more memory.
As I can’t unload .NET assemblies when activity is destroyed, I decided to keep thread and surface instead.

I don’t think it’s a good solution either, but I couldn’t think of other solutions that work with Xamarin.Android. It’s very difficult to clear all global states by myself.

For such a case I think it’s a fair solution. On low memory the app will
finally be thrown out, but as long as it is still on the “Activity back
stack”, you can keep the resources you need for a possible resume, if they
cannot be re-initialized easily.
Your solution should actually be a considerable way for handling rotation
and keyboard appearance, if they are not declared as being handled by the
app itself.

---------- P?vodn? zpr?va ----------
Od: vroad
Komu: sdl at lists.libsdl.org
Datum: 20. 6. 2016 10:03:32
P?edm?t: Re: [SDL] SDLActivity fails to finish thread in onDestroy

"

Well I now think that my app was not hanging at all. When an Android app is
requested to be killed, it simply dies even if it’s the middle of execution.
This is what happens when you manually kills an app from recent apps or from
task manager.

So problem only occurs when onDestroy is called with isFinishing() = false.
This may occurs with “Don’t keep activities” in developer option, or when
other apps request more memory.
As I can’t unload .NET assemblies when activity is destroyed, I decided to
keep thread and surface instead.

I don’t think it’s a good solution either, but I couldn’t think of other
solutions that work with Xamarin.Android. It’s very difficult to clear all
global states by myself._______________________________________________
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org"