Logo
HOW TO
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
 
 
Windows Phone

Windows Phone 7 Programming Model : Application Execution Model

4/26/2013 4:05:46 PM

Windows Phone 7 is not currently a multitasking operating system, which begs the question: how does the operating system handle application switching and state? In this section, the Windows Phone 7 application execution model is discussed in detail. We starts with an overview of the user experience, and then detail what happens under the hood. Finally the section explains how to manage application state within the available framework.

NOTE

Microsoft announced at Mobile World Conference in February 2011 that support for multi-tasking scenarios will be added to Windows Phone 7 later in 2011.

1. User Experience

If you have a Windows Phone 7 device, you are familiar with the navigation model. You know that the Start and the Back hardware button play an important role in the navigation model. The navigation model is similar to web browser navigation, which suggests that the phone maintains a back-stack of pages previously visited. Given that third-party applications do not multitask with other third-party applications in the current release, this brings up an intriguing question: what happens when you navigate back to a previous third-party application?

You probably noticed in previous examples that if you dynamically loaded data either via code or a remote service call, if you hit the Start button and then the Back button, the Resuming... screen is displayed and the application UI is rendered, but is missing the dynamic data. This happens because, while the operating system keeps a record in the back-stack of which apps have run previously, it does not maintain application state. Applications have a responsibility with the operating system to restore the application to its previous state.

2. Event Lifecycle

If you are a Windows Forms or WPF developer, you are familiar with these four events related to application life cycle:

  • Launching: Application initially loads

  • Closing: Application is excited by the user

  • Activated: Application comes to the foreground

  • Deactivated: Application loses focus

On Windows Phone 7, these events retain their general meaning, but with a twist. Launching and Closing work as expected. The Launching event fires upon initially launching the application. Closing fires upon exit.

The Deactivated event fires when the application loses focus when a hardware button is tapped, a phone call comes in, and so on. But the twist is that instead of continuing to run, the application is shut down, and an entry in the back-stack is made.

If the user navigates back to the application via the placeholder in the back-stack, the Activated event fires and the application resumes. Even though the application is no longer running when the Deactivated event fires, the Closing event does not fire. Same when the application launches upon resume in the Activated event; the Launching event does not fire.

For this section, the code for calling REST+JSON services in the CallingRemoteServices project is copied into this project to give us some interesting data to work with. We add additional code to log what is happening via the Visual Studio Output window using Debug.WriteLine, so as to not interfere with basic application functionality, but to let us know what is happening.

NOTE

Configure both the WcfRemoteServicesSimpleRestJSON and AppExecutionModel projects as startup projects for the solution to ensure the service is running.

The application lifecycle events are not attached to the individual pages, like MainPage.xaml. Instead, the events are attached to the Application object directly via the Microsoft.Phone.Shell.PhoneApplicationService class as part of the Application.ApplicationLifetimObjects collection. The lifecycle events are already created for you when you start a new project. In this project a few more events are added to the code:

  • Application_Startup

  • Application_Exit

  • MainPage - PhoneApplicationPage_Loaded

  • MainPage - PhoneApplicationPage_Unloaded

  • MainPage - PhoneApplicationPage_BackKeyPress

The application uses Debug.WriteLine("") to log when in an event handler. Let's now run the application, close the application, and then review the logged events in the Output Window.

In App constructor
In Application_Startup
In Application_Launching
In MainPage Constructor
In PhoneApplicationPage_Loaded
In PhoneApplicationPage_BackKeyPress
In Application_Closing
In Application_Exit

Let's next load the application, click the Start button, navigate back, and then hit the back button again to exit the application.

In App constructor
In Application_Startup
In Application_Launching
In MainPage Constructor
In PhoneApplicationPage_Loaded
In Application_Deactivated
'taskhost.exe' (Managed): Loaded 'System.Runtime.Serialization.dll'
In Application_Exit
...navigate to Start screen,application tombstones, and then navigate back to application
In App constructor
In Application_Startup
In Application_Activated
In MainPage Constructor
In PhoneApplicationPage_Loaded
In PhoneApplicationPage_BackKeyPress
In Application_Closing
In Application_Exit

					  

You can see that the Page and Application constructors and Page_Loaded fire every time, whether as part of initial launch or when resuming from tombstoning. Same for Application_Exit. It fires whether tombstoning or actually exiting the application. You will really want to understand this event cycle to ensure that you place code in the appropriate event handler, depending on what's desired. The next section discusses how to maintain state.

3. Managing State

Let's now add state management to the code copied from the AdventureWorksRestJSONPage page in the CallingRemoteServices project. First, let's generate random state in the App() constructor and store in a variable named randomState as a string. The state will be the current DateTime.Now value when the application is launched. It will be saved in Application_Deactivated, and restored in Application_Activated. The application will use Debug.WriteLine to log the state in App.xaml.cs. Here is the code to initialize state:

if (PhoneApplicationService.Current.StartupMode ==
    StartupMode.Launch)
{
  Debug.WriteLine("In App constructor");
  randomState = DateTime.Now.ToString();
  Debug.WriteLine("Random State: = " + randomState);
}

Notice that the code in App() to initialize state checks to ensure the application is Launching and not Activating. This is because the constructor is called in both cases as shown in the previous section.

The recommended location to store application state is in PhoneApplicationService.Current.State, which is of type IDictionary<string, object>. The "key" is a string, and the state is of type object, which means it can store any serializable object, including complex objects that contain objects. Here is the code to save in Application_Deactivated and restore in Application_Activated:

// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
  Debug.WriteLine("Activating - load state");
  IDictionary<string, object> state =
    PhoneApplicationService.Current.State;
  if (state.ContainsKey("Random State"))
  {
    randomState = state["Random State"] as String;
  }
  Debug.WriteLine("Random State Restore - " + randomState);
  Debug.WriteLine("In Application_Activated");
}

// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
  Debug.WriteLine("Deactivating - save state");
  IDictionary<string, object> state =
    PhoneApplicationService.Current.State;
  state["Random State"] = randomState;
  Debug.WriteLine("In Application_Deactivated");
}

					  

The Application_Deactivated event adds the data to the State object. The Application_Activated event restores state, but first uses State.ContainsKey to make sure the state information is present before trying to retrieve the state using the key value.

Applications have 10 seconds in both Application_Deactivated and Application_Activated to complete work.If saving or loading data goes beyond 10 seconds, the operating system will end the event handler.


The following is the data from the Output window after launching the app, clicking the Start button, and then the Back button:

In App constructor
Random State: = 1/24/2011 11:59:26 PM
In Application_Startup
In Application_Launching
In MainPage Constructor
In PhoneApplicationPage_Loaded
Deactivating - save state
In Application_Deactivated
In Application_Exit
In Application_Startup
Activating - load state
Random State Restore - 1/24/2011 11:59:26 PM
In Application_Activated
In MainPage Constructor
In PhoneApplicationPage_Loaded
In PhoneApplicationPage_BackKeyPress
In Application_Closing
In Application_Exit

As an alternative, you can handle state management at the page level. In many ways, this method makes more sense, because it is easier to restore the data as close to where it is needed, as opposed to restoring in App.xaml.cs and then passing it along. The code in MainPage.xaml.cs overrides the OnNavigatedFrom and OnNavigatedTo methods as shown here:

protected override void OnNavigatedFrom(
  System.Windows.Navigation.NavigationEventArgs e)
{
  base.OnNavigatedFrom(e);
  IDictionary<string, object> state = PhoneApplicationService.Current.State;
  state["Selected Item"] = VendorsListBox.SelectedIndex;
  DataStore.Instance.SaveCollection<ObservableCollection<Vendor>>(
    DataStore.Instance.Vendors, "Vendors");
}

protected override void OnNavigatedTo(
  System.Windows.Navigation.NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
  if (PhoneApplicationService.Current.StartupMode ==
    StartupMode.Activate)
  {
    //Load data from isolated storage
    DataStore.Instance.Vendors =
    DataStore.Instance.LoadCollection<ObservableCollection<Vendor>>(
    DataStore.Instance.Vendors, "Vendors");

					  

VendorsListBox.ItemsSource = DataStore.Instance.Vendors;
    // The state bag for  temporary state
    IDictionary<string, object> state =
      PhoneApplicationService.Current.State;
    // See if the bag contains the selected item
    if (state.ContainsKey("Selected Item"))
    {
      //Set selected item on page
      VendorsListBox.SelectedIndex = (int)state["Selected Item"];
      //Scroll to selected item
      VendorsListBox.ScrollIntoView(
        VendorsListBox.Items[VendorsListBox.SelectedIndex]);
    }
  }
}

Notice that the code does not save the Vendors collection to the PhoneApplicationService.Current.State object. The application could do that, but it seems to make sense to persist the major data collections where they would normally be saved, as opposed to being temporary state. On the other hand, saving the selected item makes sense, because when the user returns to the application after resume, the user will expect to see the application state just as they left it.

When you run the application, retrieve it from the service and then tombstone it by clicking a hardware button; then click the Back button to resume. Notice that the data is restored, and the current item is selected in the VendorsListBox control. To the user, it is as if the application continued to run when it really hadn't.

Understanding and supporting good life-cycle management is critical to providing a robust user interface. With good state management, a user will not even notice that the application stopped running. 

4. Running Under Lock Screen

You can configure an application to run under the lock screen. This means that when the phone lock careen activates, the application continues to run in the foreground and is not tombstoned. This also means that the application continues to consume CPU and more importantly battery when running under the lock screen. Here is a link to the documentation:

http://msdn.microsoft.com/en-us/library/ff941090%28v=VS.92%29.aspx

There are some application scenarios in which running under the lock screen greatly enhances the user experience. An application that records GPS values while running under lock for a run tracker program is an excellent example.

It is pretty straightforward to implement running under the lock screen. Essentially configure ApplicationIdleDetectionMode to disabled in App.xaml.cs:

PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;

					  

Handle theApplication's RootFrameObscured and UnObscured events. When the application is Obscured, execute code to reduce CPU cycles as much as possible to conserve battery. In the UnObscured event, restart application functionality to restore the application or game.

Other -----------------
- Windows Phone 7 Programming Model : Bing Maps Control
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 4) - Working with Behaviors
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 3) - Creating Animations
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 2) - Brushes
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 1) - Layout
- Windows Phone 8 : Designing for the Phone - Microsoft Expression Blend
- Windows Phone 7 Programming Model : Asynchronous Programming - Background Threads
- Windows Phone 8 : Designing for the Phone - Deciding on an Application Paradigm
- Windows Phone 8 : Designing for the Phone - The Third Screen
- Windows Phone 7 Programming Model : Web Browser Control
 
 
REVIEW
- First look: Apple Watch

- 10 Amazing Tools You Should Be Using with Dropbox
 
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
 
Popular tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Popular keywords
HOW TO Swimlane in Visio Visio sort key Pen and Touch Creating groups in Windows Server Raid in Windows Server Exchange 2010 maintenance Exchange server mail enabled groups Debugging Tools Collaborating
Top 10
- Microsoft Excel : How to Use the VLookUp Function
- Fix and Tweak Graphics and Video (part 3) : How to Fix : My Screen Is Sluggish - Adjust Hardware Acceleration
- Fix and Tweak Graphics and Video (part 2) : How to Fix : Text on My Screen Is Too Small
- Fix and Tweak Graphics and Video (part 1) : How to Fix : Adjust the Resolution
- Windows Phone 8 Apps : Camera (part 4) - Adjusting Video Settings, Using the Video Light
- Windows Phone 8 Apps : Camera (part 3) - Using the Front Camera, Activating Video Mode
- Windows Phone 8 Apps : Camera (part 2) - Controlling the Camera’s Flash, Changing the Camera’s Behavior with Lenses
- Windows Phone 8 Apps : Camera (part 1) - Adjusting Photo Settings
- MDT's Client Wizard : Package Properties
- MDT's Client Wizard : Driver Properties
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro