Fast Switching and Page State in Mango

Mango From Scratch

Mango introduces fast application switching.  To implement this feature a new stage in the Sleeping Student lifecycle has been added: Dormant.  Applications are put in the dormant state when the user navigates forward, away from the application (e.g., using the Start button).

In the Dormant state all execution of the code is stopped but the application remains in memory. If the user navigates back into a dormant application, the application resumes and each page’s state is restored automatically.

Unfortunately, if the phone runs low on memory, your application may be tombstoned. In that case, the application is terminated, but if the user returns to the application you are responsible for making it appear as if the application has been alive all along.  Fortunately, tombstoned applications do retain their State dictionary, and you can use that to restore the page state.

To see this at work, let’s create a very simple application that consists of a prompt, a TextBox and a Button,

<Button
    Grid.Row="0"
    Name="GoToPage2"
    Content="Go to page 2"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Click="GoToPage2_Click"
    Grid.ColumnSpan="2"
    Margin="128,4" />
<TextBlock
    Grid.Row="1"
    HorizontalAlignment="Right"
    VerticalAlignment="Center"
    Text="Page Data:"/>
<TextBox
    Grid.Row="1"
    Grid.Column="1"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    Name="PageData"
    Width="150"
    Text="" />

 

The button is used to navigate to a second page (from which you can return to the first page using the back button),

private void GoToPage2_Click( 
    object sender, RoutedEventArgs e )
{
    NavigationService.Navigate(
        new Uri( "/Page2.xaml", UriKind.Relative ) );
}

 

When you navigate away from the page the OnNavigatedFrom method is called.  If the navigation is backwards, the page will be disposed of and there is no need to store the state. Otherwise, we store the state in the State object, which is a dictionary that will persist through tombstoning (but not through application termination).

protected override void OnNavigatedFrom(
    System.Windows.Navigation.NavigationEventArgs e )
{
    base.OnNavigatedFrom( e );

    if ((e.NavigationMode != 
        System.Windows.Navigation.NavigationMode.Back))
    {
        State["PageData"] = PageData.Text;
    }
    
}

 

When the page is navigated to, the OnNavigatedTo method is called. We will maintain a Boolean to indicate if the user has navigated here due to a launch event (_newPageInstance == true) or after tombstoning. 

If it is not a new page, then we check to see if the page’s field is null or empty. If so, we check to see if there is data in Page State, and if so we restore.

protected override void OnNavigatedTo( 
    System.Windows.Navigation.NavigationEventArgs e )
{
    base.OnNavigatedTo( e );
    if (_newPageInstance)
    {
        if (String.IsNullOrEmpty( PageData.Text ))
        {
            if (State.Count > 0)
                PageData.Text = State["PageData"].ToString();
        }
    }
    _newPageInstance = false;

}

 

Note that in this example we are restoring a single field. A far more efficient way to approach this is to bind all the fields to a view model or other object and then store that object in PageState and restore that object, using NotifyPropertyChanged to update the UI.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Data, Essentials, Mango, Mini-Tutorial, WindowsPhone. Bookmark the permalink.

5 Responses to Fast Switching and Page State in Mango

  1. Great site. A great deal of valuable information the following. I am submitting the idea to a few good friends ans furthermore expressing inside delicious. And lastly, thanks for your perspire!

  2. Peter Wone says:

    Jessie, perhaps you recall that some months back I suggested a project wrapping the WP7 Bing map to create a speaking turn-by-turn app. You rejected the idea as too complex for your column but encouraged me to do it myself. I’ve done just that, and I am currently testing and shaking it down.

    In my travels I have uncovered a few shortcomings of the various APIs involved and I want to make some suggestions for specific points of cooperation between different teams, if perhaps you would table some items for consideration.

    Most important is the mismatch between the Bing Route API and the internal GeoCoordinate class.

    There is a widespread belief that the Bing control provided to developers is a lot slower than the one in the built-in map. This is untrue. A naiive coder will take a long route from the Bing Route service and stuff thousands of points into a PolyLine, then wonder why the map chugs.

    People with GIS experience on the other hand use a quadtree to make sample density a function of zoom level, and also clip to the display area. When you do so, map rendering is every bit as smooth as the built-in app. I have noticed the control is a little sluggish responding to touch, but this is ubiquitous and says nothing about the map control.

    But I haven’t told you this to boast about GIS experience. My point is that GeoCoordinate has a method GetDistanceTo(GeoCoordinate otherPoint) which is fast and obviously very important in map apps, and which is unavailable from the equivalent BingRoute.Location class. As a result, I find myself constantly converting collections of Locations to GeoCoordinates for comparison. This is a problem because every now and then garbage collection causes the app to become unresponsive. In the end I avoided the conversions by creating an extension method

    double GetDistanceTo(this BingRoute.Location L2)

    which implements Haversine. The shortcomings of Haversine distance computation are irrelevant over the distances considered in this sort of application but it’s not a good enough general solution for a framework, and reliable high accuracy methods are computationally intensive and would be better implemented as native code, hint-hint.

    I know I said “items” and I’ve only mentioned one. This post is already epic and I’m out of time for the moment. Have a nice day and keep up the good work.

  3. Carl Taswell says:

    This is great for what’s upcoming in Mango. But what about the current version, and what’s required for phone apps in the Windows Phone 7 Marketplace. I’ve now had the experience that the testing is not being applied consistently for what is required to pass the test for hitting the start button followed by hitting the back button so that the app survices the de-activate/re-activate sequence while retaining page state and page history. Using the same programming methods, I’ve had most apps pass but then my most recent app fail. What would be most helpful would be clarification of just what exactly is required for a pass? And a demo of best practices methods to assure a pass? Thanks! And maybe you could talk to the guys doing the testing to assure better uniformity of testing of this requirement….

Comments are closed.