Part 12 - Understanding the App’s Lifecycle and Managing State
Description
Download the source code for this lesson at http://absolutebeginner.codeplex.com/
In this lesson, we’ll briefly talk about the important moments in the life cycle of your app. Hopefully this will give you some insight as to what is going on in your app even when it is no longer running.
In a nut shell, your app is either running, it is not running (terminated) or it is suspended. What’s the difference between terminated and suspended? When a user switches to another program, chances are likely your app will be suspended for a while until the user switches back to your app. During this time, the app is in hibernation, in other words, the code in your app is not running, but the state of your application’s objects and variables including the Frame and its BackStack is kept in memory. This allows the user to switch between apps quickly and fluidly.
However, it is possible the Phone’s operating system will choose to terminate your app, which means it is removed from memory along with your application’s objects and variables. This means that the next time the user launches you app, it will have no recollection of the state of the app when it last ran. This means any work the user was doing is lost (unless you saved it), and it means that the Frame’s last page is forgotten, as is the entire BackStack.
Now, why would the Phone take a suspended app and then terminate it? There are a couple of reasons why. Usually this happens because it needs the RAM your app occupies. But it could also happen if the Phone runs out of battery or the user reboots the phone. The key is that, as an app developer, your app is notified that it is about to be suspended, however once it is suspended it is not notified about termination.
Fortunately, you can handle the Suspending() event to quickly save the state of your app before it is suspended.
Most of this work will happen in the App class. The App class is implemented in App.xaml.cs. You override those methods of the App class that you want to handle in your app. The most important is the OnLaunched method that executes each time your app is initially launched, and the OnSuspending() method which gives you a tiny window of opportunity to save the state of the app just in case it is terminated while suspended.
The App class provides a few important services that are very low level:
1. It’s the entry point for the app
2. It performs lifetime management, so when the user uses the physical buttons on the phone, or the operating system tells our app to go away for now, the App class implements methods that handle those events.
3. It manages app-scoped resources, not the least of which is the Frame object for navigation purposes. More about that in a moment. You’ll see later where I add a public property to the App class so that I can reference it throughout all pages in the app. Also, recall from the lesson on styling your app that you can create global resources and styles by defining them in the <Application.Resources> section of the App.xaml file.
4. It will also allow you to catch with unhandled exceptions in your app.
The operating system provides your app a Window to display in. Instead of allowing you to work directly with the Window, your app creates a Frame object that represents the Window, but adds navigation features … As we discussed in the lesson about navigation, the Frame object can load and unload objects that derive from Windows.UI.Xaml.Controls.Page (which each of your Pages will derive from). It also keeps a history of all the pages that were loaded and in which order in the BackStack, an IList<PageStackEntry>. Much of the setup work for the Window and Frame happens in the OnLaunched event handler.
Ok, so honestly, there are many different ways to save your data while your app is running or prior to it going into a suspended state. I’m going to demonstrate three easy ways to enable this.
The first technique is to employ the SuspensionManager. The second technique is to use Windows.Storage.ApplicationData.Current.LocalSettings. The third is to use the NavigationHelper. Now, fair warning, the SuspensionManager and the NavigationHelper are not part of the Phone API. Instead, they are helper classes that are added to your project via a project or page template. The Blank App template does NOT include these by default, however I’ll show you how we’ll add them into your project easily.
Let’s start with using no state saving techniques just to show you what the problem is. Then, we can use these three techniques to solve the problem.
We’ll create a new Blank App project called “ManagingState”.
I’ll delete the MainPage.xaml. At this point, the project will not compile because the App.xaml.cs needs a page to load at start up. We’ll fix that later.
Add a Basic Page called Page1.xaml:![]()
When you click the Add button, you’ll see the following message box:![]()
Click “Yes”. This will add both the Page1.xaml and a folder called \Common with a number of new files in it. We will not use these files just yet, but soon. Your Solution Explorer should look like this:![]()
Add two more Basic Pages, called Page2.xaml and Page3.xaml, respectively.
In all three pages, add the following code inside of the <Grid> named “ContentRoot”:
<StackPanel>
<Button Content="Go To Previous Page"
Click="previousButton_Click" />
<Button Content="Go To Next Page"
Click="nextButton_Click" />
<TextBox Name="valueTextBox" />
</StackPanel>
Also, change the TextBlock that displays the page title like so, using the appropriate name:
<TextBlock Text="page 1" Margin="0,12,0,0" Style="{ThemeResource HeaderTextBlockStyle}"/>
When you’re finished, Page1.xaml should look like this in the designer:![]()
… and the other two pages should look similar.
Add the following code to Page1.xaml.cs, at the very bottom of the class definition (right after a code region named “NavigationHelper registration”:
private void previousButton_Click(object sender, RoutedEventArgs e)
{
if (Frame.CanGoBack)
Frame.GoBack();
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
if (Frame.CanGoForward)
Frame.GoForward();
else
Frame.Navigate(typeof(Page2));
}
In a similar fashion, add the following code to Page2.xaml.cs:
private void previousButton_Click(object sender, RoutedEventArgs e)
{
Frame.GoBack();
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
if (Frame.CanGoForward)
Frame.GoForward();
else
Frame.Navigate(typeof(Page3));
}
And finally, in a similar fashion, add the following code to Page3.xaml.cs:
private void previousButton_Click(object sender, RoutedEventArgs e)
{
Frame.GoBack();
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
if (Frame.CanGoForward)
Frame.GoForward();
else
Frame.Navigate(typeof(Page1));
}
Unfortunately, all of this prep work was necessary to create a viable scenario.
If you attempt to run the application at this point, you’ll get an error:![]()
Double-click that entry in the Error List to go to the line of code that references MainPage which no longer exists in our app.
Change this line:
if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
… to …
if (!rootFrame.Navigate(typeof(Page1), e.Arguments))
and run the application.



