MOBILE

Working with the Windows Phone 7 Application Life Cycle (part 2) - Managing Application State

2/18/2011 7:57:35 PM

2. Managing Application State

Let's try the following experiment: open the Tasks project if it's not already open within Visual Studio 2010 Express for Windows Phone, and press F5 to run it. In the text box field that comes up, type "Hello, world" (you can press the Page Up key to allow you to type from the keyboard in the emulator). Next, click the Launch Browser button, and then press the Back button to return to your application.

Notice how the text box is blank (the "Hello, world" text is gone) once you come back to the main application screen. Now imagine if your application were a real-world application capturing many different pieces of data and it provided a WebBrowserTask to allow quick lookup of data on the Internet. It would certainly not be acceptable to the end user to have to retype all the information once the WebBrowserTask completes. Hence, you must devise a mechanism to preserve such data when the application is being tombstoned. Enterstate management.

If you have done any sort of web development, the concept of state management will already be very familiar to you. And if you haven't been exposed to state management before, it's a fairly easy concept to grasp. Per Microsoft's documentation, when an application like the Tasks application of the previous example is tombstoned, it should save state information in case it is reactivated. In the sections that follow, we will show you how to save and retrieve state information within your application.

2.1. Managing State at the PhoneApplicationPage Level

The concept of state management at the page level applies not only to those times when an application is about to be tombstoned and the page needs to persist its state for possible future retrieval. Many times, individual pages within a Windows Phone 7 application must save their session data to allow navigation to other pages within that same application; and if the user comes back to the original page, it should be smart enough to retrieve data previously entered by the user.

To accomplish session persistence for both tombstoning and page navigation scenarios, each page relies on the following three methods within the PhoneApplicationPage class:

  • OnNavigatedFrom(), which is called when the page is no longer an active page in a frame

  • OnNavigatedTo(), which is called when the page becomes the active page in a frame

  • OnBackKeyPress(), which is called when the hardware Back key is pressed

In the following code walkthrough, you will use each one of these methods, as well as the State dictionary object, to persist data from the text box in the Tasks application that you have built in this article. Follow these steps to accomplish this task.

You will not be making any changes to the user interface of the Tasks application—it will stay very basic, as shown in Figure 10-2. You will, however, add code to the Tasks application to persist the information that has been entered inside the single text box in that application.

  1. Launch Visual Studio 2010 Express, and open the previously created Tasks project, if it's not already open.

  2. Open MainPage.xaml.cs (one way is to right-click MainPage.xaml and select View Code). You will add code to save text entered in the text box on MainPage.xaml into the session objects if the page becomes no longer active in a frame—i.e., in that page's OnNavigatedFrom event. Add the following code to the MainPage.xaml.cs file:

    protected override void
    OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
    Debug.WriteLine("Navigated From MainPage");

    if (State.ContainsKey("TextboxText"))
    State.Remove("TextboxText");

    State.Add("TextboxText", textBox1.Text);

    base.OnNavigatedFrom(e);
    }

Notice the use of the State dictionary object—it is indeed very similar to the Session variable of ASP.NET web-based applications, and in the foregoing method we add the value from the text box into the State dictionary object.

  1. Next, you will add code to retrieve values from the State dictionary object when the user navigates to the current page; you will do that inside the OnNavigatedTo method:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs
    e)
    {
    Debug.WriteLine("Navigated To MainPage");

    if (State.ContainsKey("TextboxText"))
    {
    string strTextboxText = State["TextboxText"] as string;

    if (null != strTextboxText)
    textBox1.Text = strTextboxText;
    }

    base.OnNavigatedTo(e);
    }


The code you have written thus far is sufficient to save the text from the text box for the duration of the application session; even if an application is tombstoned, and the user later returns to the currentx page, the text will be properly preserved. Let's test this out really quickly: press F5 to run this application, enter "Hello, world" in the text box, and press the Launch Browser button. Once the browser comes up, press the Back button—you should see "Hello, world" still displayed in the text box, where we did not handle any state information at all.

While saving information for the duration of the session is extremely important, there are many occasions when you would like to save information permanently, so that even if you turn your phone off (or the battery dies), you will still have access to that information. Let's expand our walkthrough to accommodate saving text into the isolated storage on the Windows Phone 7, so that text is available for use as long as the application's isolated storage is intact (and as long as we don't remove this information from the isolated storage, of course). Follow these steps to accomplish this task.

  1. Add the following two using directives to the top of the MainPage.xaml.cs file:

    using System.IO.IsolatedStorage;
    using System.IO;

  2. You will add code to save text into the isolated storage area of your application if the user presses the Back button. If you would like to get more familiar with isolated storage. Add the following method to the MainPage.xaml.cs file:

    protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
    {
    base.OnBackKeyPress(e);
    MessageBoxResult res = MessageBox.Show("Do you want to save your work before
    leaving?", "You are exiting the application", MessageBoxButton.OKCancel);

    if (res == MessageBoxResult.OK)
    {
    Debug.WriteLine("Ok");
    SaveString(textBox1.Text, "TextboxText.dat");
    }
    else
    {
    Debug.WriteLine("Cancel");
    }
    }


Notice how the message box is used to ask the user whether to save information to the file inside isolated storage; if the user chooses Yes, the SaveString method is called, passing the value to save and the file to save it to.

  1. Finally, you need to code the SaveString method that performs all the heavy lifting within the isolated storage. This method accepts the name of the file as one of the parameters, and then it creates a file with that name within the isolated storage. After the file is created, the method saves the data string passed to it inside that file. While persisting string values inside the file is perfectly acceptable for the small application that you are building in this walkthrough, you might consider a different data structure for bigger production applications with lots of data to persist. Serializing data to XML would be a better alternative for such applications, as would be saving data inside a dictionary or key-value collection objects. Here is the full listing of that method; make sure it is also present in your code.

    private void SaveString(string strTextToSave, string fileName)
    {
    using (IsolatedStorageFile isf =


    IsolatedStorageFile.GetUserStoreForApplication())
    {
    //If user choose to save, create a new file
    using (IsolatedStorageFileStream fs = isf.CreateFile(fileName))
    {
    using (StreamWriter write = new StreamWriter(fs))
    {
    write.WriteLine(strTextToSave);
    }
    }
    }
    }


You are now ready to run your application. Press F5 to launch it, type "Hello, world" in the text box shown, and press the Back button. Remember, pressing the Back button past the first page of an application results in termination of that application. Click "Yes" on the message box prompting you to save your work before leaving. Next, re-launch your application. You should see "Hello, world" displayed in the text box—but you don't. What happened? If you guessed that we still have to retrieve the values previously stored inside the isolated storage, you are correct. We will retrieve those values in the next section, together with looking at the best practices for retrieving this information.

2.2. Retrieving Application Initial State

Microsoft guidelines state that within the Application_Launching event there should not be any isolated storage access or web service calls, so that the application comes up and is available for use as quickly as possible. Instead, Microsoft recommends asynchronously loading values from the isolated storage of an application once the application is fully loaded. This set of restrictions forces us as developers to code the initialization routines using the following two guidelines:

  1. Invoke data initialization and retrieval on a separate thread so as to maximize the responsiveness of an application.

  2. Perform application initialization inside the OnNavigatedTo method of the PhoneApplicationPage class.

In the next walkthrough, you will add the necessary methods to properly load application data from the isolated storage.

  1. You will continue modifying the Tasks project that you have worked with throughout this article. At the top of MainPage.xaml.cs, add the following using directive:

    using System.Threading;

  2. Open MainPage.xaml.cs and go to the OnNavigatedTo method within that code. You will make adjustments to that method to load data asynchronously (on a separate thread) from the isolated storage, if there is no data in the State dictionary. Make the OnNavigatedTo method look like the following:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs
    e)
    {
    Debug.WriteLine("Navigated To MainPage");

    if (State.ContainsKey("TextboxText"))


    {
    string strTextboxText = State["TextboxText"] as string;

    if (null != strTextboxText)
    textBox1.Text = strTextboxText;
    }
    else
    {
    LoadAppStateDataAsync();
    }

    base.OnNavigatedTo(e);
    }

  3. The GetDataAsync method is responsible for invoking a method that accesses isolated storage data on a separate thread. The full method is shown here:

    public void LoadAppStateDataAsync
    {
    Thread t = new Thread(new ThreadStart(LoadAppStateData));
    t.Start();
    }

  4. Finally, the GetData method accesses isolated storage data looking for a particular file (hard-coded to be "TextboxText.dat" at the moment) and the settings within that file:

    public void LoadAppStateData()
    {

    string strData = String.Empty;

    //Try to load previously saved data from IsolatedStorage
    using (IsolatedStorageFile isf =
    IsolatedStorageFile.GetUserStoreForApplication())
    {
    //Check if file exits
    if (isf.FileExists("TextboxText.dat"))
    {
    using (IsolatedStorageFileStream fs = isf.OpenFile("TextboxText.dat",
    System.IO.FileMode.Open))
    {
    using (StreamReader reader = new StreamReader(fs))
    {
    strData = reader.ReadToEnd();
    }
    }
    }
    }

    Dispatcher.BeginInvoke(() => { textBox1.Text = strData; });

    }


  5. Your application is now complete, and it should handle both transient and persistent states. To test it, press F5 and enter "Hello, world" in the text box presented. Next, press the Back button and answer "Yes" to save work before leaving. The application is now terminated; if you press F5 again to re-launch the application, the screen should come with "Hello, world" already populated within it.

3. Best Practices for Managing the Application Life Cycle on the Windows Phone 7 OS

Microsoft provides an important set of guidelines to follow to ensure a consistent and positive user experience on a Windows Phone 7 platform. Some of the highlights of those best practices are as follows.

  1. Ensuring that when the user launches a new instance of an application, it is clear that it's a new instance (in other words, our last example of automatically retrieving settings from the isolated storage may not be ideal). At the same time, if an application is being reactivated, the user should feel that the reactivated application has returned in its previous state.

  2. Since the user may never return to the application once it becomestombstoned, any data that needs to be saved to a persistent data store should be saved with either the Closing or Deactivated event fires.

  3. Invoking a launcher or a chooser will always deactivate an application and may cause it to become tombstoned. An application may not be tombstoned if it launches an experience that feels like it's a part of the original application. Microsoft currently lists the following launchers and choosers as not automatically tombstoning the calling application (it clarifies, however, that an OS may still choose to tombstone the calling application if the resources are needed elsewhere):

  • PhotoChooserTask

  • CameraCaptureTask

  • MediaPlayerLauncher

  • EmailAddressChooserTask

  • PhoneNumberChooserTask

  • MultiplayerGameInvite [games]

  • GamerYouCard [games]

You can take a look at the full list of best practices for managing the application life cycle at http://msdn.microsoft.com/en-us/library/ff817009(v=VS.92).aspx.

Other  
  •  Mobile Application Security : SymbianOS Security - Development and Security Testing
  •  Mobile Application Security : SymbianOS Security - Introduction to the Platform
  •  Java Mobile Edition Security : Permissions and User Controls
  •  Integrating Applications with the Windows Phone OS : Working with Launchers and Choosers
  •  Introducing Windows Phone 7 Launchers and Choosers
  •  Java Mobile Edition Security : Development and Security Testing (part 3) - Code Security & Application Packaging and Distribution
  •  Java Mobile Edition Security : Development and Security Testing (part 2) - Reverse Engineering and Debugging
  •  Java Mobile Edition Security : Development and Security Testing (part 1) - Configuring a Development Environment and Installing New Platforms & Emulator
  •  Java Mobile Edition Security : Configurations, Profiles, and JSRs
  •  Programming the Mobile Web : Performance Optimization
  •  Programming the Mobile Web : Testing and Debugging (part 3) - Client-Side Debugging
  •  Programming the Mobile Web : Testing and Debugging (part 2) - Server-Side Debugging & Markup Debugging
  •  Programming the Mobile Web : Testing and Debugging (part 1) - Remote Labs
  •  Windows Phone 7 : Working with Controls and Themes - Adding Transition Effects
  •  Windows Phone 7 : Working with Controls and Themes - Understanding Frame and Page Navigation
  •  Windows Phone 7 : Working with Controls and Themes - Panorama and Pivot Controls
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 5) - Windows Mobile & BlackBerry
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 4) - Windows Mobile & BlackBerry
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 3) - webOS & Android
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 2) - iPhone, iPod, and iPad
  •  
    Top 10
    Next – Gen Broadband – Optimizing Your Current Broadband Connection (Part 4)
    Next – Gen Broadband – Optimizing Your Current Broadband Connection (Part 3)
    Next–Gen Broadband – Optimizing Your Current Broadband Connection (Part 2)
    Next–Gen Broadband – Optimizing Your Current Broadband Connection (Part 1)
    Side Channel Attacks Explained
    Canon EOS M With Wonderful Touchscreen Interface (Part 3)
    Canon EOS M With Wonderful Touchscreen Interface (Part 2)
    Canon EOS M With Wonderful Touchscreen Interface (Part 1)
    Canon Powershot G15 With Immaculate Photos And Superb Controls
    Fujifilm XF1 - Compact Camera With Retro Design
    Most View
    Advice Centre by Photography Experts (Part 1) - Nikon D300
    Toshiba Stor.E Steel S Titanium 500GB
    Useful apps for iPad (Part 1) : Bento for iPad & Numbers 1.5 for iPad
    MasterClass: How To Automate Your Life (Part 1)
    Blind SQL Injection Exploitation : Using Time-Based Techniques
    New Restrictions On Old Office Software (Part 1)
    iOS Tips (Part 1) - Proof of industry shift
    Jexaa Jex Tab Evo: Slow and Bad
    Windows Vista : Recovering Systems (part 1) - Dealing with system instability
    Combine Multiple Events into a Single Event
    Windows Server 2003 : Clustering Technologies - Command-Line Utilities
    System Center Configuration Manager 2007 : Developing the Solution Architecture (part 3) - Developing the Server Architecture
    Nokia 808 Pureview - Best For Convergists
    Next – Gen Broadband – Optimizing Your Current Broadband Connection (Part 4)
    100 Ways To Speed Up Windows (Part 1)
    Secure Your Smartphone (Part 1)
    IIS 7.0 : Managing Administration Extensions
    Programming .NET Components : Remoting - Application Domains (part 2) - The AppDomain Class, The Host App Domain
    Sageone Payroll : The rock of wages
    Fine-Tuning Windows 7’s Appearance and Performance : Balancing Appearance and Performance