Fast app resume for Windows Phone 8
[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]
This topic describes how to enable fast app resume for Windows Phone 8 apps. On Windows Phone 8, when the user navigates away from an application, the application is suspended and its state is preserved in memory. If the user returns to the application by pressing the Back button or by using the Task Switcher, the app instance resumes. Because the app was preserved in memory, the app quickly resumes in the same state it was when the user navigated away. This process is called Fast App Switching (FAS). If the app is suspended and the user relaunches the app, such as by tapping on the app name in the app list or tapping the app’s primary Start Tile, by default the old instance of the app is terminated and a brand new instance of the app is created. This process is slower than resuming a suspended app and provides a different user experience. Windows Phone 8 introduces the ability for apps to request that user actions that would typically relaunch the app, such as tapping the app’s Start Tile, instead resume the suspended instance of the suspended app instance, if one exists. This feature is called Fast Resume. For more information on the lifecycle of a Windows Phone app see App activation and deactivation for Windows Phone 8.
Enabling Fast Resume is easy. It only requires a small change in the app manifest file. However, once you have enabled fast resume, there are a few different options for how your app can manage the back stack of previously visited pages when your app resumes. This topic will walk you through the different ways you can optimize the resume experience.
Direct3D apps do not distinguish between a fresh launch and an app relaunch. These apps always resume the previous experience. XAML and Direct3D apps as well as Direct3D with XAML apps can participate in fast resume like typical XAML apps.
This topic contains the following sections.
To enable Fast Resume for your app, add the ActivationPolicy attribute to the DefaultTask element in WMAppManifest.xml and set the value to “Resume”. For this task, you need to edit the app manifest directly instead of using the manifest editor. To do this, right-click WMAppManifest.xml, click Open with, and then choose XML (Text) Editor.
Fast Resume can be enabled for XAML apps, Direct3D apps, and Direct3D with XAML apps. The following examples show how the DefaultTask element will look for a XAML app and for a Direct3D app.
When implementing Fast Resume, you must decide what is the best user experience for you app when launched from the different launch points that are available on the phone.
A primary launch point takes the user to the app’s main page. Primary launch points include the app’s Primary Tile on the Start screen, the app name in the app list or the Games hub.
A deep link navigates the user to a another page within the app. Deep links include Secondary Tiles, toast notifications, extensibility points such as Search or the Photos Hub.
With Windows Phone apps, the system maintains a history of pages that the user has visited within the app, allowing the user to use the Back button to navigate backwards through the stack to previously visited pages. With Fast Resume, when an app is resumed, the system creates a new page instance for the target of the launch point and this page is placed on top of the app’s existing backstack. When this occurs, your app can choose to clear the existing backstack, leaving only the newly created page on the stack. In this case, the user experience will be that of a “fresh” app launch. If they navigate backward from the resumed app, there are no pages in the history, so they will return to the Start screen or the previous app. The other way to handle Fast Resume is to cancel navigation to the newly created page. In this case, the user will arrive on the app page that they last viewed and the backstack from their previous session will be intact. It will appear as though their previous app session simply resumed.
The following examples will consider the different user experiences for a typical XAML app. The XAML app is comprised of three pages.
Page 1 – Accessible via a link from the Main Page
Page 2 – Accessible from a secondary tile pinned to Start
Assume the user launches the app, arriving at the Main page, then navigates to Page 1, and then presses the Start button. The following illustration shows the app’s current backstack.
Assume the user uses the phone and at some point she launches the app again, from Start, using the app’s primary tile. At this point, the system creates a new page for the Uri associated with the tile, which in this case is the Main page, and places that page at the top of the backstack. This is how the backstack looks now.
What the user sees now is the app’s Main page. When she hits the Back button, she will go through Page1 and then Main page again, before pressing the back button exits the app. This is not what the user expects. Because the user just launched the app from the Start and the Main page was displayed, she expects that one press of the Back button will return her to the Start screen.
At this point, you need to decide what is the best user experience for your app. For example, you can decide that if a short time has passed since the user left the app, the last page she was viewing will be displayed when the app is resumed, and that if a long time has passed since the user left the app, the Main page will be displayed.
The “fresh instance” experience
To provide a ‘fresh’ experience, remove all pages on the backstack when the app resumes, before the user is presented with the Main page. In the following diagram, you can see that the previously visited pages have been removed from the backstack and pressing the Back button will exit the app.
The “resume” experience
To resume the previous experience when the app resumes, cancel the navigation to the Main page. This way, the user lands on Page 1 and Back takes them to Main page, as they would expect.
Resuming the previous experience makes the most sense if the app is launched from a Primary launch point, such as the primary tile on Start. For deep links, it makes more sense that apps clear the backstack . The following example illustrates the reason why.
Consider the original scenario where the user launches the app, navigates to Page 1 then presses the Start button. The following diagram shows the app’s backstack.
Assume that sometime later, the user launches the app again, this time from a secondary tile on Start. The tile’s Uri is a deep link pointing to Page 2. What the user sees now is Page 2. When she presses Back, she will go through Page 1 and then the Main page again, before she can exit the app. Again, this is not what the user expects. In this scenario, it is desirable that the application clears the backstack before the navigation to Page 2 is made.
When the application is resumed, the system raises the Navigated event on the RootFrame with the NavigationMode value of Reset.The value Reset signals that the app is being relaunched.At this point the app can clear the page stack by calling RemoveBackEntry() on the RootFrame until the backstack is cleared.
Next, the new page is created and navigated to with the NavigationMode value of New.
When the application is resumed, the system raises the Navigated event on the RootFrame with NavigationMode value of Reset. If the app doesn’t need to clear the previous pages, the page at the top of the backstack receives OnNavigatedTo with the NavigationMode value of Reset and then OnNavigatedFrom with NavigationMode value of New. At this point the app can cancel the navigation to the new page by setting e.Cancel = true on the NavigatingCancelEventArgs param in the RootFrame’s Navigating event.
When the app is relaunched with a Uri that is identical to that of the page at the top of the backstack, the system will not create a new page, but instead it signals the top page that it should be refreshed. There is no need to clear the backstack or cancel the navigation.
In this case, the page at the top of the backstack will be navigated to twice, once with NavigationMode value of Reset and a second time with NavigationMode value of Refresh. When this second navigation occurs, the app can choose to refresh its state, such as pulling down updated data from the cloud.