Mobile app lifecycle events handling in Delphi XE5

Posted by on in Blogs
The lifecycle of a mobile app is more complex and different from a desktop app. On a mobile device an application runs either in the foreground or in the background. When a phone calls arrive or when user opens another app, our app is going to background. If you are a programmer, you might be interested in responding to changes in the application state, for example saving current app state when your app goes into the background or refreshing the screen after moving into foreground.

Main two mobile operating systems, iOS and Android, fully support multitasking as their UNIX ancestor does. You would be surprised how many apps are constantly executing on your mobile device. On iOS just press the button below the screen twice, and a toolbar at the bottom of the screen will popup showing all executing apps. On Android devices you can also see all executing apps, but how you access the Task Manager may vary across devices. On my Nexus 7 tablet there is a special button next to "Home" button at the bottom of the screen to show the list of currently running apps.

The lifecycle of the application on Android is slightly different than on iOS. At the "developer" sections of web sites for both platforms you can find lifecycle charts. I have included them here for convenience.



Android app lifecycle is described at the http://developer.android.com/reference/android/app/Activity.html



iOS app lifecycle is described at the https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

Delphi XE5 makes it possible use the same source code and just recompile your mobile app for Android or for iOS. There are differences in architecture of different services on different platforms. The FM Component Platform, also known as "FireMonkey", contains "FMX.Platform" unit, which provides common interfaces to services on different platforms. It also contains an interface definition of a "IFMXApplicationEventService" that makes it possible register an event handler to receive app lifecycle events.
type
TApplicationEvent = (aeFinishedLaunching, aeBecameActive, aeWillBecomeInactive,
aeEnteredBackground, aeWillBecomeForeground, aeWillTerminate, aeLowMemory,
aeTimeChange, aeOpenURL);

TApplicationEventHandler = function(AAppEvent: TApplicationEvent; AContext: TObject): Boolean of object;

IFMXApplicationEventService = interface(IInterface)
['{F3AAF11A-1678-4CC6-A5BF-721A24A676FD}']
procedure SetApplicationEventHandler(AEventHandler: TApplicationEventHandler);
end;

I just could not resist and decided to build a simple demo project to see what kinds of events my Delphi Mobile FireMonkey app would receive on different devices!

In your application code you need to define a function with the same signature as "TApplicationEventHandler". Basically it can be any function that takes "TApplicationEvent" and "TObject" parameters and returns "boolean".

Than you need to retrieve a reference to "IFMXApplicationEventService" from a global "TPlatformServices" class and register the app lifecycle event handler passing the reference to our event handler function as a parameter to "SetApplicationEventHandler" method of the service.

The "TPlatformServices" class contains "class" property called "Current" that returns the reference to "TPlatformServices" global, singleton implementation, so there is no need to instantiate it in our code.

Depending on the platform certain services may or may not be implemented, so you always need to check whether a given service is available. It is easy to use the following patterns to obtain references to different FireMonkey platform services. If the service is implemented in the "IFMXAService" interface, than we could use the following code snippet to access it:
 var aFMXAService: IFMXAService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXAService, IInterface(aFMXAService)) then
begin
// call methods defined in the IFMXAService:
// aFMXAService.AMethod;
end
else
// FMXAService is not supported

Below is full code for a simple demo form that just registers the app lifecycle event handler and the handler itself displays the name of the lifecycle event and the time it was received in a memo component.
unit Unit11;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
FMX.Memo, FMX.Platform, FMX.StdCtrls;

type
TForm11 = class(TForm)
Memo1: TMemo;
ToolBar1: TToolBar;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
procedure Log(s: string);
public
function HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
end;

var
Form11: TForm11;

implementation

{$R *.fmx}

{ TForm11 }


procedure TForm11.FormCreate(Sender: TObject);
var aFMXApplicationEventService: IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(aFMXApplicationEventService)) then
aFMXApplicationEventService.SetApplicationEventHandler(HandleAppEvent)
else
Log('Application Event Service is not supported.');
end;

function TForm11.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
begin
case AAppEvent of
aeFinishedLaunching: Log('Finished Launching');
aeBecameActive: Log('Became Active');
aeWillBecomeInactive: Log('Will Become Inactive');
aeEnteredBackground: Log('Entered Background');
aeWillBecomeForeground: Log('Will Become Foreground');
aeWillTerminate: Log('Will Terminate');
aeLowMemory: Log('Low Memory');
aeTimeChange: Log('Time Change');
aeOpenURL: Log('Open URL');
end;
Result := True;
end;

procedure TForm11.Log(s: string);
begin
Memo1.Lines.Add(TimeToStr(Now) + ': ' + s);
end;

end.

In the experiment I have compiled the application for "iOS Device" and "Android" targets. When the demo app started on the device, I have switched to another app and then back to the demo app.



In both cases the app has received "Became Active", "Entered Background" and "Will Become Foreground" events. On Android the demo app additionally received "Finished Launching" event at the beginning of the execution "Will Become Inactive" just before receiving "Entered Background".

Below there are screenshots from my iPhone 4S running iOS 6 and Nexus 2013 tablet running Android 4.3 running "LifecycleDemo" project.





The FM Component Framework ("FireMonkey") provides common abstractions for different functionality supported on different operating systems. In this way we do not need to maintain different code bases for working with different APIs! This also means hiding the underlying complexity of individual API from a programmer, so the application code can be simpler and more easy to understand and maintain!

There are more cool services to explore in the "FMX.Framework" unit! Give it a try:-)

The source code for the "LifecycleDemo" can be downloaded from Code Central.


About
Gold User, Rank: 9, Points: 364
Crazy about Delphi Programming!

Comments

  • Guest
    Arie Monday, 30 September 2013

    pressing the home button twice on iOS does not show a list with all apps that are running, but shows all apps that have started in the past, even if they are shutdown. In general only a few apps (left in the list) and the most important standard apps (phone, messages, music) are really running, the rest is shutdown and removed from memory.

  • Guest
    Adrian Gallero Monday, 30 September 2013

    OpenUrl doesn't work in FireMonkey. QC 115594
    The event is never registered, but you can workaround it but manually registering yourself. The bug is there since XE4.

  • Guest
    Kevin P. Wednesday, 2 October 2013

    Cool.

    How large is the final, release version of the application for each platform?

  • Guest
    mobile App Saturday, 23 November 2013

    We'd love the opportunity to discuss with you how you can put YOUR Business in the Palm of your Customer's Hand! Please Contact Us for more information. We design Custom mobile App The complete Mobile Marketing Solution for YOUR. Our services Mobile Intelligence Business webpicasso, mobile strategy Mobile Intelligence, Mobile Websites, mobile App, Web & Interactive Design, Google Analytics, Mobile Marketing.

  • Guest
    mobile App Saturday, 30 November 2013

    We make the web development opportunity to discuss process very simple without confusing you with complex jargon and unnecessary headaches. We plan the process well in advance in conjunction with our clients, and we use the latest technologies which speeds the process and makes We design Custom mobile App The complete Mobile Marketing Solution for YOUR. Our services Mobile Intelligence Business webpicasso, mobile strategy Mobile Intelligence, Mobile Websites, mobile App, Web & Interactive Design, Google Analytics, Mobile Marketing.

  • Guest
    Kathy Griffin Tuesday, 7 January 2014

    I won't go into so much details. What I would like to say is that today, if you really want to make business and personal events successful then you have to use mobile event application for sure. In fact, most business owners are using event apps to make their business summits successful and fruitful.

  • Guest
    Dison Monday, 14 April 2014

    My XE5 android app freeze after bring back from backgroud, and the only solution is restart the app.

    After some time being in background, when I re-activate it, the whole App dont respond.

    some advice?

    DP

  • Guest
    Pablo Parra Monday, 12 May 2014

    Hello,

    I found a problem when my application works with modal dialog boxes in android because when the phone is blocked while the dialog box is displayed the application does not respond to unlock the phone again.

    Can you help me with this problem?.

    Best Regards,

  • Guest
    Fraz Thursday, 5 June 2014

    Pawel, you might want to update this for XE6 as application even scoping has changed. See my post at https://forums.embarcadero.com/messageview.jspa?messageID=657231&stqc=true If you change the following lines it should work for XE5 or XE6.

    TApplicationEvent.aeFinishedLaunching: Log('Finished Launching');
    TApplicationEvent.aeBecameActive: Log('Became Active');
    TApplicationEvent.aeWillBecomeInactive: Log('Will Become Inactive');
    TApplicationEvent.aeEnteredBackground: Log('Entered Background');
    TApplicationEvent.aeWillBecomeForeground: Log('Will Become Foreground');
    TApplicationEvent.aeWillTerminate: Log('Will Terminate');
    TApplicationEvent.aeLowMemory: Log('Low Memory');
    TApplicationEvent.aeTimeChange: Log('Time Change');
    TApplicationEvent.aeOpenURL: Log('Open URL');

  • Guest
    Hoby Smith Tuesday, 17 June 2014

    Awesome! Thanks much for posting this! :)

  • Guest

    [...] Articolo di Pawel Glowacki sulla gestione degli eventi delle applicazioni [...]

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: