Android OnClose OnDestroy Finalize

I’m writing a cross platform (Android and Windows) application and came across something that I can’t find an answer to.

I want to save my preferences file and free some objects when my app closes. For the Windows platforms the OnClose OnDestroy and unit Finalization all work as expected but as far as I can tell they never fire in the Android application.

OnCreate and OnShow do seem to work in Android like they do in Windows.

I did find OnSaveState, but that seems to fire both when the app loses (or regains ?) focus as well as when it closes.

What is the best way to save files and clean up memory when an Android app closes? Do I even need to bother freeing objects I created that exist for the whole application run time?

Not sure about OnFormDestroy and OnFormClose in FMX

The event properties I see are

    property OnClose;
    property OnCloseQuery;
    property OnDeactivate;
    property OnDestroy;

In my application the IDE allocates FormCreate(Sender: TObject) to OnCreate and FormDestroy(Sender: Tobject) to OnDestroy.

I have had no noticeable problems with FormDestroy but on Android I find that if I want to do things in form create like populate ComboBox options out of a database I have to do that in a FormCreateComplete function which is fired by a TTimer action. I understand that this is because Android somehow has a delayed form build and not all components fully exist at FormCreate. (I do not have any confidence in this analysis I just found a delayed “Completion” of FormCreate fixed the problem so that is my goto solution when these problems happen. )

Sorry, I meant OnClose and OnDestroy for the form events. I’ve fixed the title and post.

For me they fire for Windows platforms, but not for Android.

As for the OnCreate timing, I haven’t seen any issues with that as I’m reading the preferences file in OnCreate but not using it until OnShow.

Why do you believe they are not firing? Is this based on a break point in OnDestroy not breaking?

In the past no break points worked on my “cheap” Samsung. Support told me my phone was “too slow”. Recently they did start working again on that phone maybe due to a phone update but I am vaguely aware that maybe a breakpoint in “ondestroy” might have been missed on that phone. I assumed the destroy functionality worked just my “too slow” phone did not catch the break.

The breakpoints I added don’t work and the code in there to save the file doesn’t execute.

Have you checked the Android Style view that the events are still assigned in that?

image

They seem to be. I can’t see how to unassign them selectively even if I wanted to.

I tried a phone as well as a tablet with the same result.

Hi David

I have had the problem where some of my code is not executed.
Debugging from an earlier known point helped my find this bug. I have thought about reporting the problem but cannot always reproduce it.

Anyway try deleting the dcu’s and building your project.

Regards
Graeme

FormDestroy for the main form may never be called. Same goes for OnSaveState. Why? Because for example, “force stopping” an app does not do a graceful shutdown of the app - it just forcibly removes the app (like a crash, but no actual crash).

One possibility is to use the WillTerminate application event, though I recall times when even this may not occur. It’s still far more reliable than using OnDestroy.

A better measure to ensure that anything you want to possibly restore when the app starts again, is to persist it at the first available moment, e.g. for preferences: as soon as they are changed.

Yeah, that seems to be the way forward with settings (saving them as they change). I’m guessing that this is just how Android works. You don’t really have any control over the app being closed, so you need to assume it could close at any moment without notice or opportunity to take any action.

If that’s the case then, for cross platform apps I guess you can still code the object cleanups but assume they will only be enacted on Windows. Freeing short term objects (that are no longer required) is still required of course to stop memory usage creep.

This and other issues I’ve had to deal with seem to be missing from the video tutorials that I’ve watched so far. It’s now apparent (to me) that the mobile environment is quite different to what I’m used to in Windows. Maybe @ianbarker can touch on this in a future video?

1 Like

Good call. I will definitely do this.

FWIW, on mobile platforms, and, increasingly on desktop platforms, the pattern is to save the setting change immediately it occurs. Also, where possible, code to an interface to take advantage of auto reference counting and disposal.

On mobile platforms, as you’ve discovered, apps don’t really terminate, as such. This is a blessing and a curse. Even though they don’t really terminate under normal circumstances they also get dumped by the operating system to cope with other circumstances such as low memory.

Mobile is weird. :zany_face:

The two relevant links are here:

Personally, on Windows and similar desktop targets, I found that OnCloseQuery is usually a dependable place to tidy up instances. On Mobile, as you’ve found, this event and the OnFormClose doesn’t get triggered most of the time.

The dearly missed Paweł Głowacki wrote about this in the following blog post (which I tidied up since the archive process had made a mess of the code): https://blogs.embarcadero.com/mobile-app-lifecycle-events-handling-in-delphi-xe5/

My links above are more up-to-date than Paweł’s. You can still download the example code he quotes but, to be honest, it really only contains the code you can see in the code blocks on the post and CC is deathly slow so I wouldn’t worry about it.

2 Likes