CHAPTER 10
The application lifecycle involves events such as startup, suspend, and resume. Every platform manages the application lifecycle differently, so implementing platform-specific code in iOS, Android, and Windows projects would require some effort. Luckily, Xamarin.Forms allows you to manage the app lifecycle in a unified way and takes care of performing the platform-specific work on your behalf. This chapter provides a quick explanation of the app lifecycle and of how you can easily manage your app’s behavior.
The App class is a singleton class that inherits from Application and is defined inside the App.xaml.cs file. It can be thought of as an object that represents your application running and includes the necessary infrastructure to handle resources, navigation, and the application lifecycle. If you need to store some data in variables that should be available to all pages in the application, you can expose static fields and properties in the App class.
At a higher level, the App class exposes some fundamental members that you might need across the whole app lifecycle: the MainPage property you assign with the root page of your application, and the OnStart, OnSleep, and OnResume methods you use to manage the application lifecycle that are described in the next section.
The application lifecycle can be summarized in four events: startup, suspension, resume, and shutdown. The Android, iOS, and Windows platforms manage these events differently, but Xamarin.Forms provides a unified system that allows for managing an app’s startup, suspension, and resume from a single, shared C# codebase. These events are represented by the OnStart, OnSleep, and OnResume methods that you can see in the App.xaml.cs file, whose body is empty.
Currently, no specific method handles the app shutdown, because in most cases handling suspension is sufficient. For instance, you might load some app settings within OnStart at startup, save settings when the app is suspended within OnSleep, and reload settings when the app comes back to the foreground within OnResume. It is common to store the date and time of the last activity, for example. The Xamarin.Essentials library provides the Preferences class, which makes this very simple. If you look at Code Listing 42, you can see how it works.
Code Listing 42
using App1.Helpers; using System;
using Xamarin.Forms;
namespace App1 { public partial class App : Application { public App() { InitializeComponent();
MainPage = new App1.MainPage(); }
private DateTime _lastActivityTime; protected override void OnStart() { _lastActivityTime = Preferences.Get("LastActivityTime", DateTime.MinValue); } protected override void OnSleep() { Preferences.Set("LastActivityTime", DateTime.Now); } protected override void OnResume() { _lastActivityTime = Preferences.Get("LastActivityTime", DateTime.MinValue); } } } |
The Set method stores preferences in the form of a key/value pair. In this case, the key is an identifier used to store and retrieve the date and time of the last activity. The Get method returns the value for the specified key and allows for specifying a default value if the key is not found. In this example, the date and time of the last activity is stored at app suspension and retrieved at app startup or resume.
Xamarin.Forms includes an interesting static class called MessagingCenter. This class can send broadcast messages that subscribers can receive and take actions, based on a publisher/subscriber model. In its most basic form, you use the MessagingCenter to send a message as follows:
MessagingCenter.Send<MainPage>(this, "MESSAGE");
The Send method’s type parameters specify the types subscribers should expect, and its arguments are the sender (MainPage in this case, as an example) and the message in the form of a string. You can specify multiple type parameters, and therefore multiple arguments before the message.
Tip: The compiler is able to infer type parameters for Send, so it is not mandatory to specify them explicitly.
Subscribers can then listen for messages and take actions as follows:
MessagingCenter.Subscribe<MainPage>
(this, "MESSAGE", (sender) =>
{
// Do something here.
});
When MessagingCenter.Send is invoked somewhere, objects listening for a particular message will execute the action specified within Subscribe (this does not have to necessarily be a lambda expression; it can be an expanded delegate). When their job is finished, subscribers can invoke MessagingCenter.Unsubscribe to stop listening to a message, passing the sender as the type parameter, the current object, and the message, as follows:
MessagingCenter.Unsubscribe<MainPage>(this, "MESSAGE");
The MessagingCenter class can be very useful when you have logics that are decoupled from the user interface, and it can even be useful with MVVM implementations.
Managing the application lifecycle can be very important, especially when you need to get and store data at the application startup or suspension. Xamarin.Forms prevents the need to write platform-specific code and offers a cross-platform solution through the OnStart, OnSleep, and OnResume methods that allow handling the startup, suspension, and resume events, respectively, from a single C# codebase—regardless of the platform the app is running on. Not only is this a powerful feature, but it really simplifies your work as a developer.
Finally, you have seen in this chapter the MessagingCenter class, a static object that allows for sending and subscribing messages, which is useful with logics decoupled from the user interface.