For Microsoft Kool-Aid Drinkers, Non-paid MS Evangelists written by a Senior Consultant, Passionate about Tech

Fast App Resume for Windows Phone 8

WinPhoAppLifecycleWindows Phone 8 allows users to open an application in various ways.  Obviously, you can open an application from a tile on your Start Screen or by selecting the icon from your application list. However, Windows Phone 8 will also put your application into a suspended state when you navigate away from it.  If you want to go back to your application you can either hit the back button or use the Task Switcher.  Since Windows Phone 8 will suspend your application into memory, when it loads back up, you get right back to the state you were in when you left.  Nice right?

Well, there is a gotcha.  When you navigate away from your application, and then go to open it back up using the Start Screen or application list, it will terminate the suspended application and start a new instance of your application, hence, loosing the state the application was in when you navigated away.  Not really what the user is expecting.  Bummer huh?

Guess, what?  There is a solution.  In Windows Phone 8, there is a new feature called Fast Resume.  This feature will tell the OS to resume the application if it is suspended, otherwise, open a new one.  The best part is that this feature is really easy to turn on, and very little effort is necessary to support it in your code.

Let’s take a look.

I am going to assume that you are at the least familiar with creating a Windows Phone 8 Project.  So, go ahead and create a new Windows Phone 8 project.  Once you have created a new project, enabling Fast Resume is pretty straight forward.  However, before we do that, let’s just add a couple of things to our application that will allow us to see if things actually work.

First, let’s add a second page to the application.  Right click on the project, select Add and then select New Item….

AddNewItem

Now, select Windows Phone Portrait Page and then Add.  We can leave the Name, Page1.xaml.

AddNewPage

From here, let’s quickly change the title of the page to Test Page.  This will be the page we navigate to before we leave the application.

ChangePageTitle

Let’s also update the main page, mainpage.xaml, by changing the title to Main Page and adding a button that we will use to navigate to our new test page.

MainPage

Double click on the button and an event handler, Button_Click(),  will be added to your mainpage.xaml.cs file like below:

   1: public partial class MainPage : PhoneApplicationPage
   2:     {
   3:         // Constructor
   4:         public MainPage()
   5:         {
   6:             InitializeComponent();
   7:
   8:             // Sample code to localize the ApplicationBar
   9:             //BuildLocalizedApplicationBar();
  10:         }
  11:
  12:         private void Button_Click(object sender, RoutedEventArgs e)
  13:         {
  14:         }
  15: :
  16: :

Change the Button_Click event to navigate to our test page like below:

   1: private void Button_Click(object sender, RoutedEventArgs e)
   2: {
   3:     NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
   4: }
Run your app, hit the button on the Main Page.  You will go to our Test Page.  Now navigate to home by hitting the Windows key.  Now, go to your application list and hit your applications icon.   Notice that it brings you back to the home page.  Not what we want, but how it is intended to work. Now the Magic! To enable Fast Resume, simply open up your applications manifest file, WMAppManifest.xml,  located in your Properties folder.  Don’t double click on it.  You will need to edit it manually.  Strange that they don’t have a setting in the manifest UI for this, but oh well.  SelectManifest You should be able to right click and select Open with… SelectOpenWith Pick the XML (Text) Editor SelectXMLEditor Once you have the file open to edit, you will need to update the following line:

   1: <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>

…with this line…

   1: <DefaultTask Name="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>

Now…Save, close and Run your app and test it out.  Make sure that it works as you would expect.  Hit the button on the Main Page.  You will go to our Test Page.  Now navigate to home by hitting the Windows key.  Now,  go to your application list and hit your application’s icon.   Did it work?  What do you mean it didn’t?  Well, don’t worry, you didn’t type something in wrong (well, I guess you might have, but if you didn’t, don’t worry).

Let me explain things a little better than I did at the beginning of this post.  You see, with Fast Resume, when you return to your application, the OS resumes your app (with the applications backstack in place), adds a new instance of your starting page for your application on the backstack and displays the application.  You are probably asking yourself, “So, Fast Resume didn’t really work, cuz it took me to the starting page for my app again?”  Yes, kind of.  Like I said, it preserved the pages that were in the backstack before you navigated away and just added a new one on top of the stack.  So, try hitting the back button.  Did it go back to the previous page you were on?  No?  Gotcha again.  You see, when it resumes, the OS resets the history too, so, when you go back, you actually leave the application.  Hmm, so what do we do?  Well, there is something that is pretty quick and dirty.

First thing we need to do is add an event handler to that will allow us to cancel the page navigation to the home page.  In order to do this, we will create an event handler for Navigating() and check if we are resetting the application and navigating to the main pageOpen  up your app.xaml.cs file and scroll down to InitializePhoneApplication().  It should look like the following:

   1: private void InitializePhoneApplication()
   2: {
   3:     if (phoneApplicationInitialized)
   4:         return;
   5:
   6:     // Create the frame but don't set it as RootVisual yet; this allows the splash
   7:     // screen to remain active until the application is ready to render.
   8:     RootFrame = new PhoneApplicationFrame();
   9:     RootFrame.Navigated += CompleteInitializePhoneApplication;
  10:
  11:     // Handle navigation failures
  12:     RootFrame.NavigationFailed += RootFrame_NavigationFailed;
  13:
  14:     // Handle reset requests for clearing the backstack
  15:     RootFrame.Navigated += CheckForResetNavigation;
  16:
  17:     // Ensure we don't initialize again
  18:     phoneApplicationInitialized = true;
  19: }

Add the following code after the last RootFrame.Navigated handler like this:

   1: // Used to cancel navigation on reset
   2: RootFrame.Navigating += RootFrame_Navigating;

It should now look like this:

   1: private void InitializePhoneApplication()
   2: {
   3:     if (phoneApplicationInitialized)
   4:         return;
   5:
   6:     // Create the frame but don't set it as RootVisual yet; this allows the splash
   7:     // screen to remain active until the application is ready to render.
   8:     RootFrame = new PhoneApplicationFrame();
   9:     RootFrame.Navigated += CompleteInitializePhoneApplication;
  10:
  11:     // Handle navigation failures
  12:     RootFrame.NavigationFailed += RootFrame_NavigationFailed;
  13:
  14:     // Handle reset requests for clearing the backstack
  15:     RootFrame.Navigated += CheckForResetNavigation;
  16:
  17:     // Used to cancel navigation on reset
  18:     RootFrame.Navigating += RootFrame_Navigating;
  19:
  20:     // Ensure we don't initialize again
  21:     phoneApplicationInitialized = true;
  22: }

Next, we will need a flag that will allow the application to know if it is resetting.  So, let’s add a private bool member, appReset, to our class and default it to false.  This looks like this:

   1: private bool resetApp = false;

Add our Navigating handler, RootFrame_Navigating, with the following code:

   1: private void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
   2: {
   3:     if (resetApp && e.IsCancelable && e.Uri.OriginalString == "/MainPage.xaml")
   4:     {
   5:         e.Cancel = true;
   6:         resetApp = false;
   7:     }
   8: }

You will notice that we first check to see if we are resetting the application, that we can cancel the navigation and we are heading to or home screen.  If so, we cancel the navigation and reset our flag.  So, that is pretty easy.

One last thing, we need to make sure that we set our resetApp member in the CheckForResetNavigation() handler and prevent the ClearBackStackAfterRest from being called.  Take a look at your existing CheckForResetNavigation() method.  It looks like this:

   1: private void CheckForResetNavigation(object sender, NavigationEventArgs e)
   2: {
   3:     // If the app has received a 'reset' navigation, then we need to check
   4:     // on the next navigation to see if the page stack should be reset
   5:     if (e.NavigationMode == NavigationMode.Reset)
   6:         RootFrame.Navigated += ClearBackStackAfterReset;
   7: }

Let’s add our resetApp member code and comment out the ClearBackStackAfterReset code to look like this:

   1: private void CheckForResetNavigation(object sender, NavigationEventArgs e)
   2: {
   3:     resetApp = e.NavigationMode == NavigationMode.Reset;
   4:     // If the app has received a 'reset' navigation, then we need to check
   5:     // on the next navigation to see if the page stack should be reset
   6:     //if (e.NavigationMode == NavigationMode.Reset)
   7:     //    RootFrame.Navigated += ClearBackStackAfterReset;
   8: }

Run your app, hit the button on the Main Page.  You will go to our Test Page.  Now navigate to home by hitting the Windows key.  Now,  go to your application list and hit your application’s icon.  Bang!  Back to the Test Page.  Pretty awesome, huh?  Again, it would be even more awesome if it was a setting in the manifest editor and the application just did it for us.

NOTE:  This is just a simple approach to Fast Resume.  Depending on your application, you maybe want to do more sophisticated navigation based on splash screens, secondary tiles, timeouts, etc.

If you want to learn more about the lifecycle of a Windows Phone application, there is a great site with information here.

I hope you enjoyed this post.  Maybe this will help more applications create better user experiences.

 
Comments
 
Comments

No comments yet.

Leave a Reply

You must be logged in to post a comment.