EvenTiles from Start to Finish - Part 7
In the previous episode of this series about how to develop a Windows Phone application from scratch we used the Isolated Storage Explorer Tool to take a look at the contents of the ApplicationSettings, stored in IsolatedStorage on the device or emulator. This time we continue dealing with our application settings, because we are going to talk about Fast Application Switching and Tombstoning.
As you probably know, only one application can be running in the foreground on a Windows Phone. That application can use as much resources as it needs and should be as responsive as possible to give end users a great experience. Typically, users switch often between applications. They might not even think about different applications, because they are most likely very task oriented. To give end users the best experience, our applications share a responsibility with other applications and with the operating system.
If our application is currently running in the foreground, there are
two important reasons for our application to stop running in the
foreground:
- The user terminates our application by pressing the Back Key on the phone until the entire back stack of pages for our application is empty.
- Our application is interrupted because some sort of an event occurred.
The first situation is simple. When our application is terminating,
it is our responsibility to store information that we want to persist
until the next time our application is running. This is what we did for EvenTiles in part 5 of the series, using the Application_Launching and Application_Closing methods that are defined in the App.xaml.cs file.
NOTE: The description of Fast Application Switching and Tombstoning in this article is valid for Windows Phone Mango, not for previous versions of the operating system.
The following picture shows our application running over time. The
user navigated to the SettingsPage on EvenTiles, modified the string
value and decided to use the Start Key on the phone to start another
application. After a while, the user returns to our application by
pressing the Back Key until our SettingsPage is visible again.
For the user, this experience is great, because when they come back to our application, it shows up exactly as it was when they moved our application to the background. The operating system simply keeps our application in memory. There are some restrictions with regards to applications using certain resources like the camera. To keep our story lean and mean we will omit those. When the user starts many applications (thus putting more and more applications in the background), at some time the amount of available memory gets so low that another application can no longer be started. In this situation, the operating system decides to remove the oldest application in the background from memory, saving just minimal state information for that application. In this situation, the application that was just removed from memory is said to be Tombstoned. To restore our application from being tombstoned, we not only need to reload our application settings (as we did on the Application_Launching event), but most likely we also need to restore additional data. The Operating System ‘remembers’ the page in our application the user had visible when we were tombstoned. It is our responsibility to restore data that the user entered on that page (for instance the contents of a Textbox).
When our application is send to the background, several things happen. On the page that is currently visible, an OnNavigatedFrom event will occur. Also, the Application_Deactivated
method in the App.xaml.cs file will be called. When an application is
switched to the background, basically three things can happen to it:
- The application will become the foreground application again without having entered the tombstone state. In this situation the application can benefit from Fast Application Switching.
- The application got tombstoned, but it will become the foreground application after a while. In this situation the application must restore more state information.
- The user starts the application again by clicking its icon or tile
on the start screen. In this situation, the previous instance of the
application is removed and the user should see the application in its
initial state.
When
you are debugging your application in Visual Studio, the default
behavior when the application is moved to the background is for it to
remain in memory. However, by modifying one of the project properties
(as shown in the screen dump on the left), you can force the application
to become tombstoned, regardless from the amount of free memory on the
device (emulator). In this way, we as developers have the possibility to
test our applications in either state they enter when being moved to
the background. You should make sure that you test the tombstone
scenario for your application. For instance, if EvenTiles with its
current functionality is tested for tombstoning it will crash. This
currently has to do with the way that data is initialized. In EvenTiles,
we have a string property defined in App.xaml.cs that will later be
used to write information to the back side of our Secondary Tile. The
SettingsPage already makes use of this property. However, we are
initializing this property, named ActualBackSecContent when the application is started in the Application_Launching method.
Activating and Terminating
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
if (!appSettings.Contains(keyActSecBackContent))
{
appSettings[keyActSecBackContent] = DefaultSecBackContent;
}
ActualSecBackContent = (string)appSettings[keyActSecBackContent];
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
appSettings[keyActSecBackContent] = ActualSecBackContent;
}
Even though our application is removed from memory when it is
tombstoned, if the user navigates through the back stack using the back
key on the phone, eventually they will return back to a page of our
application. In order to make this happen in case our application was
tombstoned, it has to be reloaded again to memory to become active. In
this situation, minimal state information was stored by the
operating
system (for instance which page was the last page the user saw when our
application got tombstoned). On returning from tombstoning we will
return to that page, but since the application needs to be started
completely, classes have to be newly created and code in constructors of
those classes will therefor be executed. To distinguish between
starting a fresh copy of the application or returning from the
background, Application_Launching (fresh restart) or Application_Activated
(tombstoning or fast application switching) is called in our
App.xaml.cs file. If our application was still in memory, there is no
problem, after all, the property ActualSecBackContent still holds its value. If we are returning from a tombstoning situation we do have a problem, since Application_Activated will be called instead of Application_Launching. That is why the exception that is shown in the screen dump above was thrown.
You might think that this problem could easily be solved by
initializing the ActualSecBackContent property in the constructor of our
App class, but that would mean that we don’t benefit from fast
application switching (the situation where our application remains in
memory, even though it is in the background). A better solution is to
make use of the Application_Activated event as follows:
Switching Between BG and FG
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
if (!e.IsApplicationInstancePreserved)
{
// The application was not preserved in memory, so we were tombstoned
// Only in this case we need to re-initialize ActualSecBackContent
ActualSecBackContent = (string)appSettings[keyActSecBackContent];
}
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
appSettings[keyActSecBackContent] = ActualSecBackContent;
}
If the application is becoming the foreground application, we check if we were still available in memory. If so (e.IsApplicationInstancePreserved == true)
we don’t do anything, otherwise we just initialize the
ActualSecBackContent property. There is nothing else to do, because we
know that a value with that particular Settings key already is
available, since the application was launched at some time before Application_Activated
was called. If an application is moved to the background you want to
make sure to save everything in such a way that you assume that your
application will never return to the background. After all, the
application can stay in memory, it might be tombstoned but there is also
a possibility that the user starts a brand new instance of the
application from the start menu. In the latter case, the existing
instance of the application in the background will be removed by the
operating system.
NOTE: If you are upgrading an existing application for Mango, at the very least (after converting your project in Visual Studio) you need to only retrieve stored data in the Application_Activated method when e.IsApplicationInstancePreserved is false. In that way your application will immediately benefit from fast application switching.
The following video shows the actions we took to prevent the
EvenTiles application from crashing after being reactivated from a
tombstoned state:
With the changes that were described so far added to our application, it
no longer crashes if we are returning from a tombstone state. There are
however more things that need to be considered when the application is
brought back from background to foreground. In the next Episode of
EvenTiles we will take a look at restoring Focus on an input control
when returning from the background.
If you want to see EvenTiles already in action on your Windows Phone,
you can install the latest release from Marketplace. Remember that this
application is not meant to be extremely useful, although it contains
similar functionality that “serious” applications have. All
functionality that you can find in the released version of EvenTiles
will be covered in the upcoming episodes of this blog series, together
with all source code. Just go ahead and get your free copy of EvenTiles
from Marketplace at this location: http://www.windowsphone.com/en-US/search?q=EvenTiles (or search on your phone for EvenTiles in the Marketplace application).
Source : http://mstruys.com/2011/12/12/eventiles-from-start-to-finishpart-7/
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





