When a Windows program terminates it calls event handlers like OnClose, OnDestroy and the destructor Destroy. When I want to save some INI settings these are the places to be. I wrote event handlers for all these events but they are not processed when I terminate the program.
Does anyone know where I should place the code to be executed when an Android program terminates? I strongly suspect that this applies to iOS as well.
Update
Johan's answer works for Android as well, although reality is slightly more complicated than his examples. The nice thing was that it forced me into TApplicationEvents, something I'd never heard of. As is custom not documented by Embarcadero but the code of FMX.Platform is interesting enough. Several ApplicationEvents are defined of which three seem of interest: aeEnteredBackground, aeWillBecomeInactive and aeWillTerminate. As they are not documented I presumed that they did what their names suggested: signalling that a background state has been reached, that it wil start to go to background and that it wil (very) soon terminate. I adapted Johan's code as follows:
function TForm2.AppEvent (AAppEvent: TApplicationEvent; AContext: TObject) : Boolean;
begin
// do something here for when the app is sent to background
case AAppEvent of
(1) TApplicationEvent.aeEnteredBackground: ;// Something for OnDeactivated
// which does not exist
(2) TApplicationEvent.aeWillBecomeInactive: if Assigned (OnDeactivate)
then OnDeactivate (Self);
(3) TApplicationEvent.aeWillTerminate: if Assigned (OnClose)
then OnClose (Self);
end; // case
Result := True; // let iOS/Android know it worked...
end; // AppEvent //
When I label the events 1, 2 and 3 experiments with the debugger showed the following: forcing the application to the background generates a sequences of events: 2, 1, 1, 2. Once I even got 2, 2, 1, 1, 2, 2. If your code should be executed once, then take your precautions. But Better is: the aeWillTerminate does what it advertizes: it sends a signal when the application is terminated. Time to do so is likely to be brief and I will test whether it suffices to write a TIniFile.
I tried this code in Win32 as well and that does not work. The AppEvent is not fired. That forces me to test the code immediately on my tablet which takes some time. Pity.
When the user leaves your activity(Screen), the system calls onStop() to stop the activity. If the user returns while the activity is stopped, the system calls onRestart(), quickly followed by onStart() and onResume(). Hence writing the code and placing it in the body of onStop() method is recommended.
http://developer.android.com/images/training/basics/basic-lifecycle-stopped.png
In iOS applications seldom close but enter a background mode.
This is why the OnClose event does not fire. I suspect that killing an app by clicking on the 'x' in the taskmanager actually forcefully terminates the app, but haven't tested this. in any case this use case is too rare to code against.
In Android things work pretty much the same.
Luckily Anders Ohlsson has written a very informative blog post about this subject, see here: http://blogs.embarcadero.com/ao/2013/05/01/39450.
The following post builds on that to catch the actual backgrounding https://forums.embarcadero.com/message.jspa?messageID=558241
The trick is to register for application events. See: http://docwiki.embarcadero.com/Libraries/XE5/en/FMX.Platform.TApplicationEvent
Some sample code for iOS don't have Android handy, sorry.
Copy from the above forum:
Obviously these events should have triggered sensible event handlers in FMX.Platform.TApplication but they don't. http://docwiki.embarcadero.com/Libraries/XE5/en/FMX.Forms.TApplication_Events
Perhaps you should extend TApplication to add these eventhandlers so that sanity can be preserved.
I recommend filing a QA report.
Here's a suggestion for the extended TApplication class.