Application lifecycle management - Build Windows® 8 Apps with Microsoft® Visual C#® and Visual Basic® Step by Step (2013)

Build Windows® 8 Apps with Microsoft® Visual C#® and Visual Basic® Step by Step (2013)

Chapter 4. Application lifecycle management

After completing this chapter, you will be able to

§ Understand the application manifest settings.

§ Use the application manifest to modify application capability and appearance.

§ Deploy and test an application.

§ Understand the way Windows 8 manages the different running states of an application.

§ Respond to launching, activation, suspending, and resuming events.

§ Use the application data store to save data locally.

The preceding chapters showed how Microsoft Windows 8 provides a new user interface and a completely new user experience, while it offers a new set of application programming interfaces (APIs) called Windows Runtime APIs (WinRT) to interact with the operating system. You also developed a simple application in Chapter 3.

This chapter introduces the complete application lifecycle in Windows 8: from deployment to launching to uninstallation. You will start by analyzing the various settings in the application manifest that let you define your application’s appearance on the Start screen and inform Windows 8 about the WinRT features the application will use. You will also gain insight into how the WinRT manages the application lifecycle at runtime, launching, suspending, resuming, and terminating the application.

First, consider that a Windows 8 application cannot include an app.config file. This means that, as in a Microsoft Silverlight or Windows Presentation Foundation (WPF) Web Browser Application, you cannot use the classic .NET configuration mechanism to provide application and system settings. There are no System.Configuration namespace or equivalent classes in the WinRT APIs. The runtime system runs Windows Store applications in a sandboxed process like a Silverlight or WPF Web Browser Application. This means that users cannot navigate to the file system where the application is installed and change some files, because Windows 8 apps are mainly downloaded and installed from the Windows Store.

Application manifest

As in a Windows Phone 7.x project, many configuration settings and most deployment information are stored in a manifest file that the Windows Runtime calls Package.appxmanifest. This XML file describes various aspects of the project, as shown in the following listing, taken from a real Windows Store application.

<?xml version="1.0" encoding="utf-8"?>

<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">

<Identity Name="ea15f786-9bb0-4d64-98b0-d251fa375633"

Publisher="CN=Devleap" Version="1.0.0.1" />

<Properties>

<DisplayName>Learn with the Animals</DisplayName>

<PublisherDisplayName>ThinkAhead</PublisherDisplayName>

<Logo>Assets\Store_Logo.png</Logo>

</Properties>

<Prerequisites>

<OSMinVersion>6.2.1</OSMinVersion>

<OSMaxVersionTested>6.2.1</OSMaxVersionTested>

</Prerequisites>

<Resources>

<Resource Language="x-generate" />

</Resources>

<Applications>

<Application Id="App" Executable="$targetnametoken$.exe"

EntryPoint="ThinkAhead.Windows8KidsGames.App">

<VisualElements DisplayName="Learn with the Animals" Logo="Assets\logo.png"

SmallLogo="Assets\small_logo.png" Description="Learn animal noises, names,

guess their noises and names, try to read and try to write their names"

ForegroundText="dark" BackgroundColor="#464646">

<DefaultTile ShowName="noLogos" WideLogo="Assets\wide_logo.png" ShortName=

"Learn with the Animals" />

<SplashScreen Image="Assets\splash_screen.png" BackgroundColor="#b4dfba" />

<InitialRotationPreference>

<Rotation Preference="landscape" />

<Rotation Preference="landscapeFlipped" />

</InitialRotationPreference>

</VisualElements>

</Application>

</Applications>

</Package>

The first section, called Properties, contains information used by the Windows Store, such as the title of the application, the name of the publisher, the official logo, and a brief description.

The last section, called Capabilities, contains every operating system feature the application will use on the user’s PC or tablet. When the application code requests one of these features, the user receives a direct request to give the application specific permission to use the feature. The user can revoke this permission at any time: your code must fail gracefully if a user denies your application permission to use a capability.

This scheme has many similarities with a Windows Phone 7.x project, where the WMAppManifest.xml tells the operating system which capabilities the application requires to run. You can find more information on the application capabilities in Chapter 6.

Figure 4-1 shows the Manifest Designer that Microsoft Visual Studio 2012 provides to simplify the application definition. To open the designer, simply double-click the Package.appxmanifest file in Solution Explorer. The figure presents the real manifest for one of the authors’ applications, called “Learn with the Animals.” The Application UI tab lets you choose the Display Name of the application (name used for the Start screen), the description of the application, three logos for the application, and so on.

The Application UI tab.

Figure 4-1. The Application UI tab.

The first tab of the Visual Studio Manifest Designer produces the following section in the application manifest.

<VisualElements DisplayName="Learn with the Animals" Logo="Assets\Logo.png"

SmallLogo="Assets\SmallLogo.png" Description="Learn with the Animals"

ForegroundText="light" BackgroundColor="#222222" ToastCapable="true">

<LockScreen Notification="badgeAndTileText" BadgeLogo="Assets\BadgeLogo.png" />

<DefaultTile ShowName="allLogos" />

<SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#000000" />

</VisualElements>

The VisualElements tag, as the name implies, defines the display name for the Windows 8 Start screen, the various logos for the tile (Logo), for the small tile (SmallLogo), and for the wide tile (WideLogo), as well as the supported rotation and the default one, the badge default logo, and the image for the splash screen.

All the required images referenced by the application package manifest are provided as placeholders by the Visual Studio templates for Windows Store applications, and are placed in the Assets folder of the project. The default template accepts an image for the application logo used for the default application tile (Logo.png), an image for the initial splash screen (SplashScreen.png), and a small logo image that is shown in the tile if the application changes its tile from code (SmallLogo.png). Last but not least, it also accepts the image used by Windows Store to represent the application (StoreLogo.png). As you can see from the Figure 4-1, you can also provide a wide logo to be displayed if the user chooses a wide tile for the application on the Start screen.

Figure 4-2 shows the application tile in the Windows 8 Start screen. The tile presents the image described in the application manifest as the WideLogo property and, as you will learn in Chapter 9, the application can also modify the tile from code or create a secondary tile.

The “Learn with the Animals” wide tile on the Start screen.

Figure 4-2. The “Learn with the Animals” wide tile on the Start screen.

Application package

The application manifest contains all the information the system uses to deploy the application on the target machine, which can be the local machine or the Windows 8 Simulator (useful for testing and debugging purposes), as well as all the information needed to package the application for the Windows Store.

When you run an application from Visual Studio using the F5 key, Visual Studio 2012 compiles the application, builds the application package, and asks the operating system to install the package on the developer machine, or on the Windows 8 Simulator.

Visual Studio lets you package and deploy the application on the Windows Store by using the Store menu, Create App Package feature. This menu item launches the Create App Packages wizard that helps you package the application and upload it to the store—or simply build the package to use it on a developer machine, as you can see from the options and descriptions in Figure 4-3.

The Create App Packages wizard.

Figure 4-3. The Create App Packages wizard.

If you choose the first option to publish the application, you will be asked for the Windows Live ID you associated with your Windows Store account. In both cases, the last step of the wizard lets you choose which processor architecture you want to build the application for, and then creates the package (see Figure 4-4).

Create App Packages wizard lets you choose the output location, version, and configuration.

Figure 4-4. Create App Packages wizard lets you choose the output location, version, and configuration.

The package contains one binary file that represents the application and a folder with four different files:

§ <App Name_Version_Compilation>.appxupload. This is the real “package” and contains the compiled application that will be installed. For example, the application “Learn with the Animals,” version 1.0.0.6 for the “Any CPU” is packaged in a file calledLearnwiththeAnimals_1.0.0.6_AnyCPU.appxupload. This is the file for the Windows Store.

§ <App Name_Version_Compilation>.cer. This certificate is used to sign the application in the local development environment. The private key is contained in the .pfx file of the Visual Studio 2012 project. During the installation process this certificate is added to the Trusted Root Certification Authorities of the local machine.

§ <App Name_Version_Compilation>.appxsym. This file contains debugging symbols.

§ Add-AppxDevPakage.bat. This file contains the script to install the application, the signing certificate in the Trusted Root Certification Authorities, and all the dependencies the application needs to run.

NOTE

You can use the batch file to install the application on a developer machine manually.

When the application is installed on the system, Windows 8 creates a directory in the X:\Users\<username>\AppData\Local\Packages\ using the Globally Unique Identifier (GUID) associated with the application. This GUID is generated automatically when the Create App Packages wizard creates a new Windows Store application and is stored in the application manifest in the Identity tag, as shown in the following excerpt:

<Identity Name="380ac04e-991e-4e5f-8758-5f56e68b0e94" Publisher="CN=DevLeap"

Version="1.0.0.2" />

You can uninstall an application at any time by selecting its tile and choosing Uninstall from the Windows 8 Start screen. As shown in Figure 4-5, you can also unpin the application by clicking the Unpin From Start item in the App Bar. The unpin operation simply removes the tile from the Start screen; it does not uninstall the application from the system. You can reach the application again by pressing Windows+Q, and searching for the application among the installed apps.

Windows 8 Start screen App Bar.

Figure 4-5. Windows 8 Start screen App Bar.

The Windows Store

The Windows Store let users search, download, install, and review applications. You can upload your apps to the Windows Store by following some easy steps to make your applications available for every tablet and PC all around the globe.

The first step is to create a Windows Store account and bind it to a Windows Live ID. This procedure is quite straightforward and lets you define the publisher name—that is, the name of the application seller that the Windows Store screens display near the application name. The Windows Store lets users find applications by name, by keywords, and by publisher.

After creating an account, you can upload an application immediately, or you can reserve a name for an application you plan to develop within a year. If you plan to sell the application, you must also fill out a fiscal profile for the person or the company designated as the publisher. You will also need to fill out an IRS module related to your fiscal position. For example, if you are the publisher and you live outside of the United States, you will need to fill out the W8-BEN form. Fortunately, a wizard will guide you through the process of choosing the right module and filling it out online.

You can upload and sell an application before you have completed all the fiscal data, but you will receive no money until you have completed the fiscal data.

Aside from these “bureaucratic” tasks, the process of publishing an application is straightforward. The first thing you should do is verify that your application conforms to the Windows Store requirements locally. This step is not required, but it’s very useful because you can validate your application quickly before performing any upload. To verify your application, use the application verifier (Windows Application Cert Kit) that validates an application for technical compliance with the Windows Store rules, as shown in Figure 4-6.

The Windows Application Cert Kit verifies that an application conforms to Windows Store rules.

Figure 4-6. The Windows Application Cert Kit verifies that an application conforms to Windows Store rules.

The tool can also validate a desktop application or a desktop device application for Desktop App Certification. The Windows Application Cert Kit is installed on your system together with Visual Studio Express for Windows 8; you can launch it from the Start screen.

The next step lets you choose which application you want to validate (remember to first deploy it to the local system by compiling the project in release mode). The compliance validation begins by launching the application. It is very important that you do not interact with the application (and the system) during the validation process. The test also verifies whether the application can suspend and resume correctly, as well as close and terminate.

If your application does not pass all the tests performed by the Windows Application Cert Kit, there’s no point in trying to upload the application package to the Windows Store; the store service runs the same verification process and your application cannot pass store certification if it is unable to pass local validation. At the end of the validation process you will receive a detailed report about any problems, presented as either errors or warnings. As stated, the local verification step is not required, but it’s very useful.

After your application has completed local certification successfully, if you haven’t already reserved a name for your app, you need to choose an application name before uploading the package.

For every application, you must provide such required information as the application name and the selling details (price, availability for country, trial versions), and you can include details about age rating (which is especially important if your app is a game), information cryptography mechanism, and some notes for the tester, as shown in Figure 4-7.

The Submit An App page allows you to fill in information about your application when submitting it to the Windows Store.

Figure 4-7. The Submit An App page allows you to fill in information about your application when submitting it to the Windows Store.

Next, you need to upload the package. You can build the package directly from Visual Studio 2012, as you saw in the previous section of this chapter, by choosing the option to associate the package with the application on the store. From a practical viewpoint, after you create an application using the Windows Store dashboard you can associate it with the Visual Studio project using the Store menu. This association modifies the application manifest using the publisher name and publisher ID taken from the store services.

From the Store menu, you can select Associate App With The Store menu item to bind the project to an application, and import the publisher name and certificate in the project. You can also make this association when building the application package, as shown in Figure 4-8.

Associate an application Visual Studio project with the real Windows Store application.

Figure 4-8. Associate an application Visual Studio project with the real Windows Store application.

After completing the upload operation, you will fill in an important form linked with the Description button that lets you define all of the marketing details for the application.

§ Description of the application in plain text

§ Two lines describing major application features

§ Seven keywords

§ The optional copyright information and license terms

§ Eight optional screenshots, each one with a required description

§ Some promotional images used by the system if your app is elected to be cited in the New Apps or Top Apps pages of the store

§ Application minimum hardware requirements

§ An email to be used for support requests

§ A privacy policy

For example, Figure 4-9 shows some of the attributes used for the “Learn with the Colors” application, which is a Windows 8 app the authors published in the Windows Store.

Attributes for the authors’ “Learn with the Colors” app.

Figure 4-9. Attributes for the authors’ “Learn with the Colors” app.

For each application, the store service provides statistics such as the store trend, the financial summary, the number of downloads, the reviews, and the rating information.

Launching

When you create a new Windows Store app using the Visual Studio template, you will end up with a solution containing one project with a default page called MainPage.xaml and a class that represents the application defined in the App.xaml.cs file. The Windows Runtime invokes the method called OnLaunched immediately after the creation of the application instance. You can override this method in your application to perform some activities.

Understanding the OnLaunched event

In this procedure, you will start coding event handlers for application events.

1. Create a new Application project. To do that, open Visual Studio 2012 and from the File menu, select New Project (the sequence can be File | New | Project for full-featured versions of Visual Studio). Choose Visual C# in the Templates tree and then Windows Store from the list of installed templates, and then choose Blank App (XAML) from the list of available projects.

2. Select version 4.5 as the target .NET Framework version for your new project (this step is not necessary in Visual Studio Express edition).

3. Name the new project ALMEvents, and then choose a location on your file system and accept the default solution name. When you have completed these actions, click OK.

As you saw in Chapter 3, the Windows Store Application template provides a default page (MainPage.xaml), an application entry point in the App class (App.xaml.cs), a default application description and a declaration in the Package.appxmanifest, as well as four default images representing logos and a splash screen.

4. Open App.xaml.cs in Visual Studio, and scroll down until you can see the OnLaunched method.

The Windows Runtime calls this method when the user launches the application (an application is launched when a user clicks on the application tile). The default code inside the method simply instantiates a new Frame class, sets it as the current content, then navigates to the main page calling the Navigate method on the frame and passing the MainPage class. The last line activates the current content that is the Main Page. The code also contains a test to check for the presence of an existing frame (meaning the application is already running) that will be explained later in this chapter.

The following snippet shows the OnLaunched method.

protected override void OnLaunched(LaunchActivatedEventArgs args)

{

Frame rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,

// just ensure that the window is active

if (rootFrame == null)

{

// Create a Frame to act as the navigation context and navigate to the

first page

rootFrame = new Frame();

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)

{

//TODO: Load state from previously suspended application

}

// Place the frame in the current Window

Window.Current.Content = rootFrame;

}

if (rootFrame.Content == null)

{

// When the navigation stack isn't restored navigate to the first page,

// configuring the new page by passing required information as a

navigation

// parameter

if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))

{

throw new Exception("Failed to create initial page");

}

}

// Ensure the current window is active

Window.Current.Activate();

}

5. Add the following two lines right at the beginning of the method, before the rest of the code shown previously.

6. var dia = new Windows.UI.Popups.MessageDialog("App OnLaunched", "ALM Events");

7. dia.ShowAsync();

.....

The first line instantiates the MessageDialog class, passing to it the content and the title as string parameters. This class represents what in the past was typically called a “message box.” The second line of code shows the message dialog in the default location and begins an asynchronous operation for processing the dialog, and then calls the Start method to start the operation.

8. Press F5 to start the application or deploy the application, as you learned in Chapter 3, and click or tap the application tile.

image with no caption

As you can see, the dialog is shown full screen and displays the title and the content passed as parameters in the class constructor.

9. Click or tap the Close button to close the dialog. You will see a completely black page because the default page doesn’t present any content yet.

10.Click the Windows button to open the Start screen (you can also move the mouse in the lower-left corner of the screen and choose Start from the Start screen).

11.Scroll right until you find the ALM Events App and click the tile to launch it again. The application is already running, so you will not see the dialog; the Windows Runtime does not call the OnLaunched method for an application when that application instance is already loaded.

This behavior is significantly different from previous versions of Windows, where the system started a new instance of the application each time the user launched it. In Windows 8, there can be only one instance of an application running; when a user launches an already running application, the Windows Runtime just brings the currently loaded application to the foreground.

12.Close the application by pressing Alt+F4 and repeat steps 6, 7, and 8 to verify the application flow again.

The parameter received by the OnLaunched method is of type LaunchActivatedEventArgs, a class that implements the IActivatedEventArgs interface you saw in Chapter 3. This interface is implemented by different classes that serve as event arguments for different activation events. The first property of the interface is Kind and can assume one of the values defined in the ActivationKind enumeration. This property lets the developer ask how the application was launched, for instance. When the application was launched by a user, this property will be ActivationKind.Launch. When the application was launched by the system when a user selected it as search target, the property will be ActivationKind.Search. When the application was activated so it could receive something from another application using a Share contract, the property will be ActivationKind.ShareTarget. In C# and VB there are two different methods in the base class to react to this activation. You will see these different methods later in this chapter.

Showing the launch kind

In this procedure, you will change the code of the previous procedure to show the type of activation.

1. Replace the code you inserted in the previous procedure for the OnLaunched method to create a message that contains the activation kind as follows. The lines in bold have to be inserted.

2. String message = "App Launched: " + args.Kind.ToString();

3. var dia = new Windows.UI.Popups.MessageDialog(message, "ALM Events");

4. dia.ShowAsync();

5.

...

The first line uses the Kind property of the event args to build the message text, and the second line presents it in a message dialog.

6. Run the application, deploying it from the Build menu. Then start the application by clicking the application tile in the Start screen. You will see the dialog presenting the text “App Launched: Launch.”

7. Click Close, but do not shut down the application.

8. Go to the Start screen and click the application tile. Again, this time you will see no messages because the application is already running.

9. Close the application using Alt+F4.

Understanding the previous state

In this procedure, you will modify the code for the OnLaunched method to test the execution state for the previous launch of the application. If the user closed the application normally, the previous execution state will be ClosedByUser—letting you know that everything went well for the user. If the user has never launched the application, the previous execution state will be NotRunning.

1. Change the first line of the OnLaunched event to build a more detailed message that shows the activation kind and the previous execution state by replacing the first line of the method with the one shown in the following code excerpt (bold line):

2. String message = "App Launched: " + args.Kind.ToString() +

3. " - Previous State: " + args.PreviousExecutionState.ToString();

4. var dia = new Windows.UI.Popups.MessageDialog(message, "ALM Events");

5. dia.ShowAsync();

...

6. Deploy the application using the Build | Deploy menu item.

7. Start the application by launching it from the Start screen.

8. Verify that the message displays “App Launched: Launch – Previous State: ClosedByUser,” meaning the application was previously closed by you (if in fact you did close it in the previous procedure). The message will be “App Launched: Launch – Previous State: NotRunning” if the application was closed immediately before this launch. Try closing it and launching it from the Start screen quickly.

9. Close the application using Alt+F4.

10.Modify the MainPage.xaml by adding two buttons and their corresponding click events in the Grid control as follows.

11.<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

12. <StackPanel Orientation="Horizontal" VerticalAlignment="Top">

13. <Button Click="Crash_Click" Content="Crash" />

14. <Button Click="Close_Click" Content="Close" />

15. </StackPanel>

</Grid>

The first button will be used to perform an invalid operation that causes the crash of the application. The second will be used to gracefully close the application from code.

16.Implement the event handlers for the Crash_Click and the Close_Click events (in bold) using the following code in the MainPage.xaml.cs file:

17.using System;

18.using System.Collections.Generic;

19.using System.IO;

20.using System.Linq;

21.using Windows.Foundation;

22.using Windows.Foundation.Collections;

23.using Windows.UI.Xaml;

24.using Windows.UI.Xaml.Controls;

25.using Windows.UI.Xaml.Controls.Primitives;

26.using Windows.UI.Xaml.Data;

27.using Windows.UI.Xaml.Input;

28.using Windows.UI.Xaml.Media;

29.using Windows.UI.Xaml.Navigation;

30.

31.// The Blank Page item template is documented at http://go.microsoft.com/

32.fwlink/?LinkId=234238

33.

34.namespace ALMEvents

35.{

36. /// <summary>

37. /// An empty page that can be used on its own or navigated to within a Frame.

38. /// </summary>

39. public sealed partial class MainPage : Page

40. {

41. public MainPage()

42. {

43. this.InitializeComponent();

44. }

45.

46. private void Crash_Click(object sender, RoutedEventArgs e)

47. {

48. Int32 a = 10;

49. Int32 b = 0;

50.

51. Int32 c = a / b;

52. }

53.

54. private void Close_Click(object sender, RoutedEventArgs e)

55. {

56. Application.Current.Exit();

57. }

58.

59. /// <summary>

60. /// Invoked when this page is about to be displayed in a Frame.

61. /// </summary>

62. /// <param name="e">Event data that describes how this page was reached. The

63. Parameter

64. /// property is typically used to configure the page.</param>

65. protected override void OnNavigatedTo(NavigationEventArgs e)

66. {

67. }

68. }

}

69.Deploy the application by right-clicking the project in the solution and choosing Deploy from the context menu.

70.Launch the application from the Start screen, click Close on the dialog, and then click the Crash button on the main page. The application should crash, returning you to the Start screen in a few seconds. Be patient.

71.Launch the application again from the Start screen. The dialog will show “NotRunning” as the previous state.

72.Close the dialog and then click the Close button on the main page to close the application gracefully.

73.Launch the application again from the Start screen to verify that the dialog shows “NotRunning” as the previous state.

74.Close the dialog and then close the application by using Alt+F4 or by swiping your mouse or finger from the upper-center of the screen to the lower-center of the screen to close the application in the canonical way.

75.Wait for at least 20 seconds and then launch the application again from the Start screen to verify that the dialog shows “ClosedByUser” as the previous state.

To summarize, an application receives a call to the OnLaunched method from the Windows Runtime when the user launches the application and the application is not already running. This method receives the launch kind and the previous state. You have also learned that there can be only one instance of a Windows Store app running in Windows 8.

Activation

If the user “launches” an application indirectly, using the Search contract, the application receives a call to the OnSearchActivated method as you saw in Chapter 3. The Windows Runtime terms this procedure “activation,” as the name of the method implies. Activation is a more correct term because the application isn’t launched directly by the user. The parameter args received by the OnLaunched method, as you saw in the preceding procedure, has a property called Kind that can assume the value of Search. But don’t be confused by this; when the user selects the target of his or her search, the Windows Runtime invokes the OnSearchActivated method on the App class and never invokes the OnLaunched events. Both event arguments, as well as other event args for other activation methods, implement a common interface; this explains why both have the same property. The following procedure clarifies these concepts.

Understanding the OnSearchActivated Method

In this procedure, you will modify the code for the App.xaml.cs file to test the activation for search. You will use the Search Contract template proposed by Visual Studio and that you learned about in Chapter 3.

1. Implement the Search contract by right-clicking the project in the Solution Explorer and choose Add New Item.

Scroll down until you find the Search contract item.

2. Click the Add button without changing the default name and select Yes when the dialog box asks you to add the requested files.

You will not implement a real search page in this procedure, but just test the activation for searching.

Adding the Search contract item modifies the Package.appxmanifest to declare the Search contract and adds the following line in the App.xaml.cs file.

protected async override void OnSearchActivated(

Windows.ApplicationModel.Activation.SearchActivatedEventArgs args)

{

// TODO: Register the

// Windows.ApplicationModel.Search.SearchPane.GetForCurrentView().QuerySubmitted

// event in OnWindowCreated to speed up searches once the application is already

running

// If the Window isn't already using Frame navigation, insert our own Frame

var previousContent = Window.Current.Content;

var frame = previousContent as Frame;

// If the app does not contain a top-level frame, it is possible that this

// is the initial launch of the app. Typically this method and OnLaunched

// in App.xaml.cs can call a common method.

if (frame == null)

{

// Create a Frame to act as the navigation context and associate it with

// a SuspensionManager key

frame = new Frame();

ALMEvents.Common.SuspensionManager.RegisterFrame(frame, "AppFrame");

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)

{

// Restore the saved session state only when appropriate try

{

await ALMEvents.Common.SuspensionManager.RestoreAsync();

}

catch (ALMEvents.Common.SuspensionManagerException)

{

//Something went wrong restoring state.

//Assume there is no state and continue

}

}

frame.Navigate(typeof(SearchResultsPage1), args.QueryText);

Window.Current.Content = frame;

// Ensure the current window is active

Window.Current.Activate();

}

3. Add the three bolded lines just at the beginning of the OnSearchActivated method.

4. protected async override void OnSearchActivated(

5. Windows.ApplicationModel.Activation.SearchActivatedEventArgs args)

6. {

7. String message = "App Activated by the Search Contract";

8. var dia = new Windows.UI.Popups.MessageDialog(message, "ALM Events");

9. dia.ShowAsync();

10.

...

11.Deploy the application. If you haven’t closed the application in the previous procedure yet, activate it and click the Close button or use the Task Manager to kill the application.

12.Press Windows+Q, type something in the search box, and select the ALMEvents App.

13.Verify that the dialog displays “App Activated by the Search Contract.”

You will not receive the dialog for the application launching because the application was not launched by the user but activated for a search. VB and C# application base classes expose different methods to respond to launch and search activations, whereas WinJS exposes just a generic activation function where you can test the activation kind property of the event args.

14.Close the application using Alt+F4.

If the user shares some content from another application, the target application receives a different activation called sharing target activation (OnSharingTargetActivated is the name of the corresponding method). You will learn about this kind of activation and the sharing contract inChapter 6.

There are other types of activation, each one corresponding to an operation performed by the user. Table 4-1 summarizes the principal activation types.

Table 4-1. Windows Runtime activations

Method name

Description

Activated

Invoked when the application is activated by tile activation

File Activated

Invoked when the application is activated through file-open

File Picker Activated

Invoked when the application is activated through file-dialog association

Search Activated

Invoked when the application is activated through a search association

Sharing Target Activated

Invoked when the application is activated through sharing association

Because there are several types of activations, if you want to perform some actions not related to a specific type of activation, you can override the OnInitialize method of the application class. This method is called from the runtime immediately after the application instance has been created, and before the specific method for a particular activation kind.

Suspension

The Windows Runtime introduces a new concept for application lifecycle management (ALM) that consists of a two-phase process in which the application is suspended when the user leaves it to launch or activate a different app and resumed when the user switches back to it.

The idea behind this mechanism is to maintain system responsiveness even if the user launches many applications. Only the foreground application uses significant processor time, whereas other applications are suspended by the system. There can be a maximum of two running apps (when they are in snapped mode). Usually, when not in snapped mode, there will be only one foreground app. To avoid latency when the user returns to a previously launched application, the Windows Runtime freezes the application memory when suspending an application, and places it in a special idle state: no CPU-cycle, disk, or network access is given to a suspended application. The result is that the system remains fully responsive to the foreground application while the resume operation is practically instantaneous.

Verify application suspension

In this procedure, you will check the suspension state using the same application you have been building throughout this chapter.

1. Launch the application from the Start screen. Avoid using the Visual Studio 2012 debugger to test the standard suspension behavior because this behavior changes slightly while debugging.

2. Close the dialog that displays the launching message.

3. Press Alt+Tab or the Windows key to put the current application in the background.

4. Open the Task Manager, and wait until the application goes into the suspended status. To open the Task Manager, you can press Windows+Q and search for the term “Task Manager” in the Apps list, or you can activate the Desktop from the Start screen and right-click the taskbar.

Figure 4-10 shows the result of this procedure.

Using the Task Manager to determine application state and resources.

Figure 4-10. Using the Task Manager to determine application state and resources.

NOTE

Your screen may be slightly different depending on the columns shown by the Task Manager. For example, you must manually enable the Status column for it to be visible.

As you can see, the ALMEvents App (PID 1220 in Figure 4-10) is placed in the suspended state. It uses no processor time or disk access at all, but, as previously stated, it uses 7.9 MB of frozen memory on our system. Obviously, this value may be different on your system.

Switch back to the application again (Alt+Tab) and note that the application resumes instantly without showing a launch message dialog (because it wasn’t launched; it was just resumed from the suspended state).

The Windows Runtime will suspend the app after it has been switched into the background for at least 10 seconds. If you place an app in the background for fewer than 10 seconds and then return to it, the app will probably not be suspended.

The system informs the application immediately before the suspension manager starts its work. An application has only five seconds to perform any pre-suspension operations, and if an app requires more than five seconds to perform its pre-suspension operations, the Windows Runtime may terminate it forcibly.

It is very important to understand the complete flow of the suspension/resume process before coding against it. The system suspends your app whenever the user switches to another app or to the desktop. The system resumes your app whenever the user switches back to it. When the system resumes your app, the content of your variables and data structures will be the same as it was before the system suspended the app. The system restores the app exactly where it left off, so that, to the user, it appears as if it’s been running in the background all along. There is no need to save any data the user has been working on during the suspension phase if the user comes back to the application. But, if the system does not have the resources to keep your app in memory, or needs more resources for other applications launched by the user, the system will terminate your app. Your app will not be notified of the termination because the Windows Runtime assumes you have already saved any needed data or state information during the suspension phase. When the user switches back to a suspended app that has been terminated, the app receives a different launch event, which is where you have to write the code that restores the application data.

Now that you have seen the complete flow, let’s add some code to the application you are developing in this chapter to follow the operations.

Using the Suspending event

In this procedure, you will modify the code for App.xaml.cs to intercept the suspension and display a message dialog. This is not what you would do in a real application, but it is a helpful experiment to make sure you understand the complete process.

1. Open the App.xaml.cs file.

2. In the constructor, the Visual Studio Blank App template prepares the code to hook up the Suspending event as follows.

3. public App()

4. {

5. InitializeComponent();

6. this.Suspending += OnSuspending;

}

7. Use the following code for the event handler for the Suspending event. Replace the existing code.

8. void OnSuspending(object sender,SuspendingEventArgs e)

9. {

10. String message = "App Suspending";

11. var dia = new Windows.UI.Popups.MessageDialog(message, "ALM Events");

12. dia.ShowAsync();

}

13.Deploy the application and launch it from the Start screen.

14.Close the dialog that displays the launching.

15.Click the Windows key to put the current application in the background.

16.Open Task Manager and wait until the application has been suspended.

17.When the application has been suspended, press Alt+Tab again to return to the application and verify that the message shows “App Suspending.”

This dialog was shown during application suspension but because the application was not in the foreground anymore, you saw nothing during the system operation. When you reactivate the application, the Windows Runtime resumes the application as it was prior to the suspension, which is why you can see the dialog on the screen only during the resuming operation.

In practice, the dialog is visible because the application has been resumed exactly where it was left off; the last thing the application did before the suspension was process the call to display this message. You did not see this message during the suspension because the application was already sent to the background.

An incorrect suspension example

As mentioned earlier, an application has only five seconds to respond to the suspension event. If the application requires more time, the Windows Runtime kills the application. In this procedure, you will test this behavior.

1. Close the application if you left it open in the previous procedure.

2. Open the App.xaml.cs file and comment out the existing code of the OnSuspending method and insert the bolded line from the following excerpt.

3. void OnSuspending(object sender,SuspendingEventArgs e)

4. {

5. //String message = "App Suspending";

6. //var dia = new Windows.UI.Popups.MessageDialog(message, "ALM Events");

7. //dia.ShowAsync();

8. while(true);

}

This code simply loops indefinitely—so it exceeds the five-second limit; the pre-suspension code runs “too long” for the system, so it will kill the application after the allotted time.

9. Deploy the application.

10.Open an instance of the Task Manager and minimize it.

11.Go to the Start screen using the Windows key and launch the application.

12.Maximize the Task Manager.

You can verify that after some time (maybe 20 seconds or more depending on the system) the application disappears from the application list: this means that the application was killed by the system because the code for the suspending event exceeded the maximum allowed time.

13.Launch the application again and verify the message in the dialog: it indicates the previous state as “Terminated” because the application was terminated (killed) by the Windows Runtime. This procedure can be slightly unpredictable because the runtime can decide to terminate the application later, which makes debugging code in the OnLaunched event quite difficult and time consuming if you are trying to test for a previous termination. But don’t worry, at the end of this chapter you will learn how you can simulate suspension, resuming, and termination from Visual Studio 2012 during a debugging phase.

Requesting more suspension time

If your application can’t save its state and data in five seconds and needs some more time—for example, to persist some temporary data via web services or in the cloud—you can inform the system that you are executing an asynchronous operation. Call the SuspendingOperation.GetDeferralmethod to indicate that the app is saving its application data asynchronously. When the operation completes, the handler calls the SuspendingDeferral.Complete method to indicate that the app’s application data has been saved. If the app does not call the Complete method, the system assumes the app is not responding and terminates it. When that happens, the next time the user launches the application they should not rely on the validity of the saved application data.

The SuspendingOperation has a deadline time. Make sure all your operations are completed by that time. You can ask the system for the deadline using the Deadline property of the SuspendingOperation.

In this procedure you will change the code for the event handler so it writes the suspension time on disk using an asynchronous deferred operation. Theoretically, this operation cannot last longer than five seconds, but this example shows the correct code to implement an asynchronous operation.

1. Comment out the line that performs the endless loop.

2. Add the code shown in bold in the following block.

3. void OnSuspending(object sender, SuspendingEventArgs e)

4. {

5. //String message = "App Suspending";

6. //var dia = new Windows.UI.Popups.MessageDialog(message, "ALM Events");

7. //dia.ShowAsync().Start();

8. // while(true);;

9.

10. var deferral = e.SuspendingOperation.GetDeferral();

11.

12.

13. var settingsValues = Windows.Storage.ApplicationData.Current.LocalSettings.

14. Values;

15. if (settingsValues.ContainsKey("SuspendedTime"))

16. {

17. settingsValues.Remove("SuspendedTime");

18. }

19. settingsValues.Add("SuspendedTime", DateTime.Now.ToString());

20. // Perform the aysnc operation

21. deferral.Complete();

22.

}

The first uncommented line gets the deferral from the suspending operation property of the SuspendingEventArgs class. At the end, the code reports the completion of the deferred operation to the system.

The code gets the LocalSettings property of the application data and inserts a key called SuspendedTime with the current time in the collection. The LocalSettings class lets the developer save simple key/value pairs in the local application data folder. As you will learn in Chapter 10, the Windows Runtime denies access to the classic file system and instead provides a local or roaming space, called application data, that applications can use to store data. This kind of storage is similar in many aspects to the IsolatedStorage provided by the Silverlight and the Windows Phone runtime. You can use a RoamingSettings property instead of the LocalSettings property if you want to be able to share your app data across multiple devices. RoamingSettings is a cloud-based isolated storage, which relates the data to the current user’s Windows Live ID account.

WARNING

Remember that the entire method must return before the deadline.

You can also hook the suspending event inside the code of an application page, which is very useful for saving the state of the page during the suspension so that you can restore it in case of termination. Be aware that the Suspending event is not raised in the UI thread, so if you have to perform some UI operations you have to use a dispatcher.

You can debug the code for the suspending method as usual, and you can also force a suspension during a debugging session from Visual Studio. You will try this functionality during the next procedure.

Resume

In the “Suspending” section of this chapter, you implemented a suspension event handler in the application class to calculate and save the current suspension time to the application data store.

In this procedure you will read the saved time from the application data store during the resume operation from the application class and then you will implement the code to show that same data within a page.

The resume operation is useless if the application was suspended by the system because the memory dedicated to the application is just frozen and not cleared. However, if the system needed more memory and decided to terminate the application, the resume operation is the right place to read the data saved in the suspension procedure.

You can intercept the resume operation by hooking up the Resuming event of the application class if you need to perform some application operations. For instance, you can save the page that the user was on before the suspension and, if the application was terminated, open that page instead of the default one. That’s what the following code sample does.

using System;

using System.Threading;

using System.Threading.Tasks;

using Windows.ApplicationModel.Activation;

using Windows.UI.Xaml;

namespace ALMEvents

{

sealed partial class App : Application

{

public App()

{

InitializeComponent();

this.Suspending += OnSuspending;

this.Resuming += OnResuming;

}

private static String currentPage;

private void OnSuspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)

{

var def = e.SuspendingOperation.GetDeferral();

var settingsValues = Windows.Storage.ApplicationData.Current.LocalSettings.Values;

if (settingsValues.ContainsKey("Page"))

{

settingsValues.Remove("Page");

}

settingsValues.Add("Page", currentPage);

def.Complete();

}

void OnResuming(object sender, object e)

{

var settingsValues = Windows.Storage.ApplicationData.Current.LocalSettings.Values;

if (settingsValues.ContainsKey("Page"))

{

if (settingsValues["Page"] == "CustomerDetails")

{

// Activate the Customer Details Page

}

}

}

}

}

The code is straightforward. The OnSuspending event handler saves the name of the current page in the local application data store and the OnResuming event handler reads that value when the application is resumed from a terminated state.

An application can leverage the resuming operation, performing some actions even if the application was not terminated. For example, you can request data taken from a web service or remote source if the suspend operation occurred some minutes before the resume, letting your app present fresh content to the user.

Refresh data during resume

In this procedure, you will modify the code for the MainPage.xaml.cs file to display the launch time, the suspended time, and the resuming time.

1. Open the MainPage.xaml file and add three TextBlock controls. The first one will display the time the page was first opened, the second will display the suspension duration, and the third will display the resumed time. Use the following code as a reference.

2. <Page

3. x:Class="ALMEvents.MainPage"

4. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

5. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

6. xmlns:local="using:ALMEvents"

7. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

8. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

9. mc:Ignorable="d">

10.

11. <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

12. <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="10,01,10,10">

13. <Button Click="Close_Click" Content="Close" />

14. <TextBlock Name="firstTime" FontSize="24" Margin="10,10,10,10" />

15. <TextBlock Name="suspendTime" FontSize="24" Margin="10,10,10,10" />

16. <TextBlock Name="resumeTime" FontSize="24" Margin="10,10,10,10" />

17. </StackPanel>

18. </Grid>

</Page>

19.Open the MainPage.xaml.cs file. Use the following code as a reference to hook up the resuming event to display the suspended time restored from the application state and the resumed time.

20. using System;

21. using System.Collections.Generic;

22. using System.IO;

23. using System.Linq;

24. using Windows.Foundation;

25. using Windows.Foundation.Collections;

26. using Windows.UI.Xaml;

27. using Windows.UI.Xaml.Controls;

28. using Windows.UI.Xaml.Controls.Primitives;

29. using Windows.UI.Xaml.Data;

30. using Windows.UI.Xaml.Input;

31. using Windows.UI.Xaml.Media;

32. using Windows.UI.Xaml.Navigation;

33.

34.// The Blank Page item template is documented at http://go.microsoft.com/

35.fwlink/?LinkId=234238

36.

37.namespace ALMEvents

38.{

39. /// <summary>

40. /// An empty page that can be used on its own or navigated to within a Frame.

41. /// </summary>

42. public sealed partial class MainPage : Page

43. {

44. public MainPage()

45. {

46. this.InitializeComponent();

47.

48. firstTime.Text = "Ctor : " + DateTime.Now.ToString();

49.

50. App.Current.Resuming += Current_Resuming;

51.

52. }

53.

54. void Current_Resuming(object sender, object e)

55. {

56. this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,

57. () =>

58. {

59. var settingsValues =

60. Windows.Storage.ApplicationData.Current.LocalSettings.Values;

61.

62. if (settingsValues.ContainsKey("SuspendedTime"))

63. {

64. suspendTime.Text = "Suspended : " +

65. settingsValues["SuspendedTime"].ToString();

66. }

67. resumeTime.Text = "Resumed :" + DateTime.Now.ToString();

68. });

69. }

70.

71. private void Close_Click(object sender, RoutedEventArgs e)

72. {

73. Application.Current.Exit();

74. }

75.

76.

77. /// <summary>

78. /// Invoked when this page is about to be displayed in a Frame.

79. /// </summary>

80. /// <param name="e">Event data that describes how this page was reached. The

81. Parameter

82. /// property is typically used to configure the page.</param>

83. protected override void OnNavigatedTo(NavigationEventArgs e)

84. {

85. }

86. }

}

In the constructor of the MainPage class, the second line of code assigns the current time to the first TextBlock. This code executes only when the application instantiates the page—that is, when the user launches the application or when the application is resumed from a terminated state. The code is not executed when the application is resumed from the suspended state.

The Current_Resuming event handler reads the value of the SuspendedTime key in the application data store and assigns it to the second TextBlock, and then assigns the current time to the last TextBlock. This code is not executed in the UI thread, which is why the code is executed by a dispatcher.

87.Deploy the application.

88.Launch the application from the app tile on the Start screen and close the initial dialog box.

89.Click the Windows Key and go to the Desktop.

90.Open the Task Manager and wait until the application has been suspended by the system.

Minimize the Task Manager.

91.Return to the application by pressing Alt+Tab.

image with no caption

92.Close the application using the Close button.

To facilitate debugging the suspending and resuming event, Visual Studio includes two menu items that let you ask the Windows Runtime to suspend and resume the application during a debugger session. This feature is very useful because it lets you avoid using the Task Manager as you have been doing so far, and because it lets you invoke this event sequence as needed.

Use Visual Studio to debug suspend and resume

In this procedure, you will use Visual Studio to debug the suspending and resuming events.

1. Open the App.xaml.cs file and place a breakpoint in the first line of the OnSuspending method.

2. Open MainPage.xaml.cs and place a breakpoint in the first line of the Current_Resuming method.

3. Press F5 to start a debugging session and wait until the application is visible on the screen.

4. Press Alt+F4 to return to Visual Studio. In the Debug Location toolbar, choose Suspend. If this toolbar is not visible, you can enable it using the View menu, choosing the Toolbars item, and then selecting the Debug Location item.

image with no caption

The breakpoint in the suspend event handler will be hit. Press F5 to continue. The breakpoint in the resume event handler will be hit soon because the application is taken in the foreground by Visual Studio when you pressed F5.

5. Press F5 again. Verify that the application is visible and presents the three labels with different times.

6. Press Alt+F4 to return to Visual Studio, and use the Debug Location toolbar to select Resume to verify you can directly debug the resume procedure without the need to debug the suspend procedure first. You can also click the Resume button on the debug toolbar.

7. Using the Debug Location toolbar, select Suspend And Shutdown. The application will first go into the suspended state and then be terminated by the runtime. Using this option you can debug the code for the OnLaunched event to test a previous termination.

In short, the system suspends your app whenever the user switches to another app or to the desktop, and resumes your app whenever the user switches back to it. When the system resumes your app, the content of your variables and data structures is the same as it was before the system suspended the app. The system restores the app exactly where it left off, so that it appears to the user as if it’s been running in the background. However, the app may have been suspended for a significant amount of time, so it should refresh any displayed content that might have changed while the app was suspended, such as news feeds or the user’s location.

Summary

In this chapter, you saw the complete application lifecycle at runtime. You saw how to package and install an application in the local system and how to create a package suitable for the Windows Store. Then you saw the various events that the Windows Runtime fires to launch, activate, suspend, resume, and terminate a Windows 8 app.

Quick reference

To

Do this

Create the Application Package

Use the Store menu from Visual Studio, and choose Create App Package.

Install an application locally for testing

You can use the classic F5 button to deploy and run the app automatically, or choose Deploy from the project contextual menu, or you can create the App Package and launch the batch file.

Save temporary data

Use the Suspending event from the application class.

Test Suspend and Resume

Debug the application and use the Suspend and Resume buttons on the Visual Studio Debug Location toolbar.

Uninstall an application

Go to the Start screen, right-click the tile, and choose uninstall. You can also swipe down with your finger on the tile to activate the lower toolbar.