Fast App ResumeIn continuation of the last article about the
integration into the “Photos” hub, today we will open the topic
Fast Application Resume , which appeared in WP8, and consider what it is for, and what advantages the use of this function provides, as well as various scenarios for using App Resume.
Looking ahead, I would like to mention the mentioned problem of using Fast Resume along with Photo Sharing, Push Notification, etc. As it turned out, there is no problem. Almost not. If the user has updated his phone (WP8 Update 3), then with the new update, there are no problems with switching to Url. However, a colleague
texnedo showed one interesting scenario in which there is a bug with AppResume. If App Resume is turned on in the application and the screen is locked without minimizing the application, the application is simply restored without going to the toast url.
What is App Resume for?')
With the classical model of application execution, clicking on the tile (on the desktop or when clicking on the list of applications) not only launches, but also restarts the application if it was started and minimized. In some cases, it is easier not to restart the application, but to return to an already running application as if the user had returned via the “Back” button. For “heavy” applications, it is much faster to return to the running application than to restart it and reinitialize the data, which subjectively reduces the “launch” time.
As in the case of Fast Application Switch (unlike App Resume, this ability to quickly return to a running application after minimizing the “Back” button), App Resume is not a replacement for Tombstone and you need to take into account that if the application is “asleep”, then fully save the data and restore them yourself.
Now consider how to integrate this feature into the application, consider the various return scenarios.
How to enable App ResumeTo enable this feature is quite simple: all you need to do is open the WMAppManifest.xml file in the XML editing mode (in the context menu - Open With - Xml editor) and add the attribute:
ActivationPolicy="Resume"
for the
<DefaultTask />
.
In the end, the default string in the manifest of the form:
<DefaultTask Name ="_default" NavigationPage="MainPage.xaml" />
would look like this:
<DefaultTask Name ="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
How App Resume WorksTo demonstrate the details of the App Resume, let's make a simple application with the ability to navigate between two pages. Also on both pages, we will display the value of some variable that can be changed by a button, and we will show the navigation history, including whether the application was launched or activated.
For simplicity, the value of the variable will be stored in memory in a static class in a static field and will be displayed on both pages in OnNavigateTo
static class FakeCacheStorage { public static int Counter { get; set; } }
In order to figure out exactly how App Resume works, we need to temporarily comment out the line:
RootFrame.Navigated + = CheckForResetNavigation;
in App.xaml.cs, where the handler stores the code.
First check Fast Application Switching. Run the application and increase the counter to some number (let it be 4) and see what we have before the application is minimized and returned via the “Back” button


As we expected, the difference in the way the application is launched. Initially, the application was launched, and then activated by the "Back" button.
And now let's see what it would be like if we turned the application down and instead of the “Back” button, we started the application through the main application file.

As we can see, the application was launched, not activated, and we were on the main page. In addition, the value of the variable has been reset. It is obviously necessary to restore all user data from the repository.
And now, if you include App Resume in the manifest, then, ultimately, we will see a different picture:

But this is more interesting - the application was activated, but not launched, while we were on the main page and the value of the counter is preserved! And we will see our second page only if we press the “Back” button. If we did not display the history of navigation, one would think that the application was simply restarted. The most interesting thing would have started when the user tried to exit the application using the “Back” button - for this he would have to press this button three times. Next, we look at what App Resume was done for and how we can use such scenarios for using such behavior.
App Resume as a way to "quickly launch" the applicationWhat we saw in the previous section provides interesting food for thought. We can use App Resume to quickly launch applications while preserving all data loaded into memory, but we need to get rid of the old navigation history. That is, in fact, the user must wipe out of the application using the “Back” button. If you create your WP8-application in the studio starting with version VS2012, then the necessary methods have already been added to the generated project. To review the work of App Resume, we temporarily commented out the line with the App Resume handler:
RootFrame.Navigated + = CheckForResetNavigation;
If we uncomment this line, we will not see the history of navigation.

In fact, it looks as if the application was launched (the user goes to the main page and exits the application by the "Back" button), but the data remained in memory.
Let us consider in more detail what is being done in this method.
In the InitializePhoneApplication method (app.xaml.cs file) there is a separate subscription to the Navigated event:
RootFrame.Navigated + = CheckForResetNavigation;
The navigation history is deleted by the Reset argument:
private void CheckForResetNavigation(object sender, NavigationEventArgs e) { // If the app has received a 'reset' navigation, then we need to check // on the next navigation to see if the page stack should be reset if (e.NavigationMode == NavigationMode.Reset) RootFrame.Navigated += ClearBackStackAfterReset; }
And, accordingly, further in the ClearBackStackAfterReset method, the navigation history is cleared:
private void ClearBackStackAfterReset(object sender, NavigationEventArgs e) { // Unregister the event so it doesn't get called again RootFrame.Navigated -= ClearBackStackAfterReset; // Only clear the stack for 'new' (forward) and 'refresh' navigations if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh) return; // For UI consistency, clear the entire page stack while (RootFrame.RemoveBackEntry() != null) { ; // do nothing } }
Why is there a subscription to New and Refresh? Consider on our example.
If we use App Resume, being on the second page, then we can make a breakpoint in the OnNavigateTo method on our page and see that the page starts with the New parameter. However, if we were already on the main page when the application was minimized, we would return to the main page first with the Reset navigation parameter, and only then with the Refresh navigation parameter, which is processed in this method.
Next, we will consider another interesting scenario of using App Resume - when we do not launch the application, but return to it.
App Resume to return to the running application. "As in iOS or WP8.1"It has been rumored that now applications for WP8.1 on the main tile will not be restarted by default, but restored. Like it or not, we can only find out after Build. In the meantime, we can make the behavior “like in iOS”, that is, if the user minimized the application and clicked on the main tile, it goes to the same page where it was, and the application is not restarted. It is important to understand that it is necessary to use this opportunity not to make it “like in iOS”, but in order to make a really convenient and high-quality application that will be convenient to use. In general, WP users are used to the fact that applications will most likely restart when they click on the main tile.
In fact, the user should get into his application just as if he had just switched to the application using the “Back” button, while preserving the navigation history and user data on the screen.
We need to handle two main behavioral scenarios:
1. The user clicks on the application tile.
2. The user activates the application by reference (Push Notification, Secondary Tile, Photo Share, etc.)
In the first case, to implement this scenario, first of all, turn off the reset of the history when App Resume:
in App.xaml.cs, we delete the
Navigated subscription and the CheckForResetNavigation method, subscribe to the
Navigating event (it comes BEFORE we go to the page and can cancel the transition):
RootFrame.Navigating + = ContinueExecution;
When launching the application, we can see in the method that the event comes first with the Reset argument, and then the event with the New argument when the application is clicked.
With this behavior in mind, we’ll take a closer look at the implementation of ContinueExecution:
private bool isRelaunch = false; private void ContinueExecution(object sender, NavigatingCancelEventArgs e) { if (e.NavigationMode == NavigationMode.Reset || (isRelaunch && e.NavigationMode==NavigationMode.New)) { if (isRelaunch && e.Uri.OriginalString != "/MainPage.xaml") { RootFrame.Navigated+=ClearBackStackAfterReset; return; } e.Cancel = true; isRelaunch = !isRelaunch; } }
The ClearBackStackAfterReset method is generated by the studio for new WP8 projects and simply clears the navigation history:
private void ClearBackStackAfterReset(object sender, NavigationEventArgs e) { RootFrame.Navigated -= ClearBackStackAfterReset; if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh) return; while (RootFrame.RemoveBackEntry() != null) { } }
As we can see here, the condition for checking the start page has been added:
if (isRelaunch && e.Uri.OriginalString != "/MainPage.xaml")
Validation is required for the second scenario, when the minimized application is activated by secondary tiles, push notification, etc.
In this case, the history will be cleared, and after activating the application and processing the user history using the “Back” button, we will exit the application.
If you want, for example, according to Push Notification, not to delete the history, but continue to use the application, it is enough to delete the line
RootFrame.Navigated + = ClearBackStackAfterReset;
or add another condition for links with push notification.
To demonstrate how the second script works, add a button to the next page to generate a second link:
<Button Content="Secondary Tile" Click="ButtonTile_OnClick"></Button>
Add a fairly simple handler for this button:
private void ButtonTile_OnClick(object sender, RoutedEventArgs e) { var secondTile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("issecondtile")); if (secondTile == null) { var newTileData = new StandardTileData { Title = "Second Page", }; ShellTile.Create(new Uri("/SecondPage.xaml?id=someid&issecondtile=true", UriKind.Relative), newTileData); } }
Now, if we run the application, then go to the second page. If we then click on the tile after that, we will see that the application has started without the navigation history and at the same time, the main tile is launched with the navigation history.

ResultsDespite the simplicity of App Resume, the explanation of the principles of work turned out quite lengthy. As we can see, using App Resume, you can not only speed up the launch of the application, but also make the behavior of the application “as in iOS”. It is also especially important not to forget about Tombstone in the application recovery script by tile. In this case, we will save the entire navigation history, but at the same time all user data in memory will be destroyed and we need to restore them on the screen from the storage.