In this blog post I look at the new application lifecycle model that Windows Phone 7.1 (Mango) introduces, and show how to handle the various lifecycle events in a simple MVVM application.
In a previous blog post I described the development of a simple Windows Phone 7 application using the Model-View-ViewModel (MVVM) pattern and how to handle application lifecycle events, specifically tombstoning. In this blog post I will look at updating this sample for Windows Phone 7.1 (Mango) to handle fast-app switching and the new Dormant state.
As an aside, I have bumped into a number of developers who were under the impression that Mango removes the need to tombstone. I’m afraid that this is not the case!
Introduction and a Recap
The WP7 application lifecycle model is designed to allow the user to move fluidly between applications whilst minimising the memory that these applications consume. Neither WP7 or WP7.1 (Mango) allow true multi-tasking, where more than one application is running at the same time. Instead, they employ a number of techniques to give the illusion of multi-tasking. As a developer you are exposed to this via the application lifecycle.
The WP7 (pre-Mango) application lifecycle, with the events that are fired for each transition, is illustrated below:

You can see the tasks that you must perform under each state transition.
When the user pressed the Start button, your application stops running and becomes tombstoned. It is your responsibility to save your application state such that when the user pressed the back-button (navigating the back-stack) to return to your application, it is in the same state as when they left it. This involves saving both the state of your application logic, within the application PhoneApplicationService.State dictionary and the UI state (e.g list scroll position) within the PhoneApplicationPage.State dictionary for each page. I described how you can achieve this in my previous blog post. I also want to point out that the rather tricky task of saving UI state can be made much simpler by using things like Matt Lacey’s popular Tombstoning Helper utilities.
One other thing that the Execution Model Overview on MSDN does not make terribly clear is that the back-stack has a limited size. What this means is that your tombstoned application state will not necessarily be re-activated. You can test this by running your application with the debugger attached, if you create a long enough back-stack (by repeatedly hitting the Start button and starting a new application), your debugging session will eventually terminate. This occurs when your application state has been pushed off the back-stack.
The upshot of this is that when your application is tombstoned you must save your state to isolated storage as well as the State dictionary (because your application might never get closed). Although, as it is recommended that your application tombstones swiftly, you might want to store application state to isolated storage at more regular intervals.
Windows Phone 7.1 Lifecycle
Windows Phone 7.1 (Mango) introduces a much more convincing illusion of multi-tasking, where the user can press and hold the back-button to rapidly switch between a small number of apparently concurrently running applications. However, again this is not true multitasking.
To achieve this, WP7.1 introduces a new state in the application lifecycle, the Dormant state:

When you application is in a Dormant state it is still in memory, however it is not executing. This allows the phone to re-start your application much more rapidly than when it is in a tombstoned state.
The phone can only store a limited number of dormant applications, as a result it might choose to move your application from a dormant to a tombstoned state. You do not receive any notification that this has occurred. However, the tombstoning and re-activiation process is the same as that for WP7.0, where you re-activate your application from the data saved in the State dictionary.
Again, there is always the possibility that your tombstoned data will be pushed out of the back-stack and lost.
Notice that there have not been any new events added to indicate that your application has returned from a Dormant state, your application will always receive Activated event when it is restarted regardless of whether it was dormant or tombstoned. This is good news, because it is backwards compatible with WP7.0.
Handling the Dormant State
So how do you handle this new state in your application? In order to maintain backwards compatibility you don’t strictly have to, however it is actually very simple to do.
The event arguments passed to the Activated event now have a new IsApplicationInstancePreserved argument which is true if your application has been re-started from a dormant state and false if it has been restarted from a tombstoned state. If this argument returns true, you simply do nothing! This ensures that you do not perform any redundant actions and helps your application restart faster.
The code below is all of the lifecycle code (apart from per-page UI state) that my MVVM example application contains. You can see that the code for a re-activated dormant state does nothing.
// 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) { Debug.WriteLine("Launching"); LoadViewModelFromIsolatedStorage(); // if the view model is not loaded, create a new one if (ViewModel == null) { ViewModel = new FeedViewModel(); ViewModel.Update(); } // set the frame DataContext RootFrame.DataContext = ViewModel; } // 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) { Debug.WriteLine("Activated From Dormant State"); } else { Debug.WriteLine("Activated From Tombstoned State"); LoadViewModelFromAppState(); RootFrame.DataContext = ViewModel; } } // 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) { Debug.WriteLine("Deactivated"); SaveViewModelToAppState(); SaveViewModelToIsolatedStorage(); } // 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) { Debug.WriteLine("Closing"); SaveViewModelToIsolatedStorage(); } private void SaveViewModelToAppState() { PhoneApplicationService.Current.State[ModelKey] = ViewModel; } private void LoadViewModelFromAppState() { if (PhoneApplicationService.Current.State.ContainsKey(ModelKey)) { ViewModel = PhoneApplicationService.Current.State[ModelKey] as FeedViewModel; } } private void LoadViewModelFromIsolatedStorage() { // load the view model from isolated storage using (var store = IsolatedStorageFile.GetUserStoreForApplication()) using (var stream = new IsolatedStorageFileStream("data.txt", FileMode.OpenOrCreate, FileAccess.Read, store)) using (var reader = new StreamReader(stream)) { if (!reader.EndOfStream) { var serializer = new XmlSerializer(typeof(FeedViewModel)); ViewModel = (FeedViewModel)serializer.Deserialize(reader); } } } private void SaveViewModelToIsolatedStorage() { // persist the data using isolated storage using (var store = IsolatedStorageFile.GetUserStoreForApplication()) using (var stream = new IsolatedStorageFileStream("data.txt", FileMode.Create, FileAccess.Write, store)) { var serializer = new XmlSerializer(typeof(FeedViewModel)); serializer.Serialize(stream, ViewModel); } } |
Debugging Dormant and Tombstoned state
Because the application now has a couple of states that it can be in when it is not running, you need to employ a few tricks to be able to force the application into these states while developing. Typically the emulator will always place your application into a dormant state when you hit the Start button.
The fast-app switch UI is not enabled on the emulator by default, however you can enable it with a bit of hackery as described on this forum thread.
So, if your application always moves into a dormant state, how do you test your tombstoning code? Fortunately there is a build setting which you can enable which will ensure that your application is always tombstoned rather than placed in a dormant state:

You should test your application with this setting enabled and disabled to ensure that it accommodates tombstoning and dormant state.
I hope this blog post has helps understand the slightly complex application lifecycle that Mango introduces. It is clear that this delivers the best performance to the user, however it is a little complex for the developer!
You can download my updated MVVM example here: WindowsPhoneMVVMExample.zip
Regards, Colin E.
Tags: Mango, mvvm, tombstoning, Windows Phone 7


email: ceberhardt@scottlogic.co.uk
on Google+



[...] http://www.scottlogic.co.uk/blog/colin/2011/10/a-windows-phone-7-1-mango-mvvm-tombstoning-example/ תגים:DEV, Windows Phone [...]
I see that I get e.IsApplicationInstancePreserved (true or false) depending on my debug settings.
So I think I am kind of misunderstanding application state.
My app has few pages with static text/images, which user can navigate.
So I don’t really need to save anything I guess, correct? I was under the impression that I will need to save the page info user was on when app deactivates and then upon activation, fetch that detail and navigate user to appropriate page.
Let me know I am still misunderstanding.
Thanks,
OM
Hi Om,
Sounds like your emulator is doing the right thing. I have written in detail about the application lifecycle here:
http://www.scottlogic.co.uk/blog/colin/2011/10/a-windows-phone-7-1-mango-mvvm-tombstoning-example/
It should tell you all you need to know.
Colin E.
Thanks Colin.
Yes, I got it is doing right but I need to understand more on what to save in application state.
You didn’t put wrong link correct? It is same as this article I am commenting.
Thanks again.
Hi,
I set the ‘Tombstone upon deactivation while debugging’. Save the project. Closed the emulator. Run in Debug mode but when I move around my app and click the Start button and then Back my app returns to same page as I was before.
So why my app is not tombstoning? Or am I doing something wrong to test it?
Thanks for wonderful article.
How can i handle restart of my phone
How do you mean ‘handle’ it? You should save persistent data to isolated storage. You can do this via the PhoneGap file APIs.
Great article..
First of all Thanks for answering the questions.
what is the way to start a tombstonned application?
Does this mean that any application who state has been previously saved when restarted will act as a tombstonned application.
Question 1: Is there any limit to the application save state mechanism?
I mean in the backstack?
Question 2: If a device restarts and the launches the tombstonned app what will happen to the save state?(He presses the windows button and selects the app)
Question 3: If say the state is restored, then what is the way to start a fresh application? or is it immpossible to start fresh application once the application has been tombstonned once?
Question 4: When you compare by launching a tombstonned application a dormant application – Will the performance of the App be the same? (I guess the dormant should be fast compared to tombstonned – since the application lives in the background)
Question 5: Is the only way to start a tombstonned application is by backstack only or is there any device capabilities. Like when you hold the windows button it shows the back stack? Does this mean that user has to rememmber – when was last time he openend the app?
If a device is restarted and the tombstonned applications is launched, will the state and the data be restorted??
According to the msdn and other documentations that i have gone through about Mango, says that 5 applications can stay in memory or in Dormant(sleep mode). Tombstonning is a state where the system memory is less and the application memory is collected.So it is said that we need to save the state of the application before tombstonning happens in the isolated memory.So does this mean that a Tombstonned application can come to activated state? If it can come into activated state, then what is the difference between a fresh application launch and a tombstonned applicaiton? ( In your diagram it is shown during the applicaiton launch that load app state from isolated storage)
If the application state is loaded from the isolated storage then how can we fresh start an application.
If long press of the back button gives the in memory applications (dormant applications) what is the way to start a tombstonned application?
Good questions!
You are correct, WP7.1 (Mango) can hold up to 5 applications in a dormant state, but more in a tombstoned state. However, your application does not receive any notifications when it moves from dormant to tombstoned state, so when it becomes dormant you have to save the state that you require should it become tombstoned.
1. Yes, a tombstoned application can become activated if the user navigates to it via the back-stack (i.e. repeatedly hitting the back button)
2. A fresh application will invoke the Loaded event and not the Activated event. This is how you detect the difference in code. How you handle this is up to you! MSDN states “Ensure that when your application is launched by the user from Start or the installed applications list, the user is taken to a consistent launch experience. It should be evident to the user that they are experiencing a new application instance”. How you achieve this is up to you! An RSS reader should probably store the latest items from the feeds and restore them when a new app is launched in order to avoid the need to re-fetch them. However a Word-like application should probably just display a recent-file list.
3. “what is the way to start a tombstonned application?” – you have no control over this. Your application will become dormant or tombstoned based on user actions.
Regards, Colin E.
I have a question on point # 2.
When an app becomes tombstoned it might get removed from the back-stack. In this case can it become activated if the user repeatedly presses back button? If yes, will it invoke activated event or launch event?
Thanks
You are correct, a tombstoned application can be removed from the back-stack. In this case repeated back-button presses by the user will not navigate back to your application. When the end of the back-stack is reached, the next back-button press takes the user back to the Start screen.
[...] A Windows Phone 7.1 (Mango) MVVM Tombstoning Example [...]