Preserving & Restoring Application State for Silverlight Based Windows Phone Apps

Introduction

The application tenure on mobile platforms is not very long. Frequently, users have to stop doing what they are currently doing on their mobile device and take that all important call. As a Windows Phone platform developer, if you do not account for such scenarios, your product will not appeal to the users if it loses customer data or does not remember what you were last doing in that application. This can get serious for gamers as well, who would have to start the game from the beginning, if the game could not store progress.

When to Note Application State

It is important to realize that at certain events, it is critical to note the application state. The main events where preserving and restoring state is critical are: application launch (Launching), application activation (Activated), application deactivation (Deactivated) and application termination (Closing).

Storage Facilities in the Windows Phone Platform

The Windows Phone platform allows applications to store its information at the following two locations:

IsolatedStorage: This is an isolated area for storage which only this application has access to. This ensures privacy of the data. This storage is persistent so it can be accessed across instances of the application.

State dictionary: This is a non-persistent storage location which is available only as long as the phone is either active or in the tombstoned state. This storage location is exposed as is the State property of the PhoneApplicationService object which can be accessed by the main class of the application. Since this storage is non-persistent, this data is not available if the application is terminated and re-launched.

Only data which can be serialized can be stored in the State dictionary.

Hands On

Let's use a hands-on example to illustrate how to preserve and restore application state.

Start Microsoft Visual Studio and create a new Silverlight for Windows Phone project and call it WindowsPhoneApplicationContextDemo. Start off by adding a string to represent the application data, and call it myAppDataContext. You will add this in the App call (App.xaml.cs):

  public partial class App : Application
  {
  public string myAppDataContext;
   }

You will note that in this class, there are already event handlers for the various interesting application events (Application_Lauching, Application_Activated, Application_Deactivated and Application_Closing).

Note in the Application_Launching event hander, you do not want to do anything since this is the first time the application is launched and state is not available.

However, things get interesting with the Application_Activated event. In the event handler for that event, we check to see if state exists in the State Dictionary. If it exists we can set our application data object to that value.

           // 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 (PhoneApplicationService.Current.State.ContainsKey("myAppDataContext"))
               {
                   myAppDataContext = PhoneApplicationService.Current.State["myAppDataContext"] as string;
   
               }
   
           }
 

Now, we add code to capture application context when the application is deactivated. We can also use this event to store the application context to a persistent storage like IsolatedStorage.

           private void Application_Deactivated(object sender, DeactivatedEventArgs e)
           {
               // If there is data in the application member variable...
               if (!string.IsNullOrEmpty(myAppDataContext))
               {
                   // Store it in the State dictionary.
                   PhoneApplicationService.Current.State["myAppDataContext"] = myAppDataContext;
   
                   // Also store it in Isolated Storage.
                   IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
                   StreamWriter sw = new StreamWriter(isoStore.OpenFile("myAppDataContextFile.txt", FileMode.OpenOrCreate));
                   sw.Write(myAppDataContext);
   
               }
   
           }
 

Sometimes, a user can accidentally hit the back button when on the first page of an application. In such scenarios, we don't need to update the application data context , but only save it to the persistent storage. We use the Application_Closing event for this.

   private void Application_Closing(object sender, ClosingEventArgs e)
           {
               if (!string.IsNullOrEmpty(myAppDataContext))
               {
                   IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
                   StreamWriter sw = new StreamWriter(isoStore.OpenFile("myAppDataContextFile.txt", FileMode.OpenOrCreate));
                   sw.Write(myAppDataContext);
               }
   
           }
 

Now that we have updated the App class to work with the interesting event, we can update the Page class. We will need a way to track if data needs to be reloaded in the page or not. Add a Boolean called newInstance to track this.

   public partial class MainPage : PhoneApplicationPage
       {
           bool newInstance = false;
           string mainpageDataContext;
   
   In the constructor, set the value of the tracking Boolean to true.
           public MainPage()
           {
               InitializeComponent();
               newInstance = true;
           }
 

Next we override the OnNavigateTo event like we did in the example for the "page state preservation' article. Here we add the appropriate code to either retrieve data from the persistent storage if the page has loaded for the first time or from the State dictionary otherwise. I have put the placeholders in the snippet below. The exact code to be put is left as an exercise for the viewers.

   
   protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
           {
               // Call the base implementation
               base.OnNavigatedTo(e);
   
               // If this is a new page instance, the data must be retrieved in some way
               // If not, the page was already in memory and the data already exists
               if (newInstance)
               {
   
                   // Here you will add code to retrieve the data from the persistent storage if this is the first time the application page is invoked.
   
               }
               else
               {
                   // Otherwise set the page's data object from the application member variable
               }
   
               // now set the tracking boolean to false since we have already fetched the data
               newInstance = false;
           }
 

Summary

In this article, we saw how to preserve and restore application state either persistently or non-persistently.



About the Author

Vipul Vipul Patel

Vipul Patel is a Software Engineer currently working at Microsoft Corporation, working in the Office Communications Group and has worked in the .NET team earlier in the Base Class libraries and the Debugging and Profiling team. He can be reached at vipul_d_patel@hotmail.com

Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds