2012

Volume 27

Modern Apps - The Windows Store App Lifecycle

By Rachel Appel | 2012

Rachel AppelWindows 8 is changing how and when applications run, and you’ll want to understand the nuances of the new application lifecycle so you can build apps that respond as they should at every point. Apps that conform to the Microsoft lifecycle management guidelines offer a better experience for the user, especially on small devices where memory and battery conservation are warranted.

Application Design

Two key design concepts underlie Windows Store apps: apps can run in full screen, snapped or filled mode; and apps must be highly responsive so the user can focus on the content at hand with fewer distractions. These two principles ensure that the currently running app gets all the available resources from the OS and the user, unlike Windows 8 desktop apps or apps on previous Windows versions, which had to share those resources. 

All Windows Store apps have four states: not running, running, suspended and terminated. When you launch an app, it runs. Later, depending on user or system activity, the app might transition between running and suspended states. For example, if the user switches from app A to app B, Windows suspends app A after a short delay, moving it to the background. App A remains suspended (until the user switches back to it or Windows terminates it), while app B activates and moves into the running state (possibly from a suspended state if it was already in memory). If the user returns to app A, Windows simply wakes it up and, as far as both the OS and app A know, it’s been running all along. Then, of course, it’s app B’s turn to be suspended.

When an app is in a suspended state, its code doesn’t run and the app remains in memory, as is. Essentially, the app is cached and instantly ready to go when the user switches back. However, that’s not the whole story—you can run background tasks if you follow the proper procedures, and Windows might terminate apps if memory pressure warrants it. Figure 1 illustrates how apps move between execution states (see bit.ly/TuXN9F for more information).

How Windows Store Apps Move Between Execution States
Figure 1 How Windows Store Apps Move Between Execution States

As Figure 1 suggests, an app can move between running and suspended states frequently. The app lifecycle state transitions highlight the difference between Windows Store apps and traditional desktop apps.

Visual Studio 2012 includes a rich set of debugging tools as well as a Windows Simulator (bit.ly/QzBy5I), which you can use to manage app lifecycle operations. That’s important, because you need to react appropriately to app lifecycle events and handle state transitions properly in order to create a highly responsive experience for the end user—a core principle of app design on Windows 8. By responding suitably to app lifecycle events, you can ensure users have a consistent experience throughout the app’s lifecycle. Specifically, this means saving and restoring the state of your app whenever necessary. This might entail returning the user back to where she was in your application (such as in a wizard), or repop­ulating the values of a form she was working on, or returning to the last article she was reading. Because application lifecycle is controlled by the user’s movement through an app, an app needs to be prepared to checkpoint its state at a moment’s notice—whenever the app gets the suspending event.

App Activation

The WWAHost.exe process is an app host that executes Windows Store JavaScript apps. XAML apps written with any language—such as C#, Visual Basic or C++—run the app’s corresponding executable. Either way, all apps go through activation, which has a number of catalysts:

  • The user launches an app from a tile.
  • The user switches to a suspended app.
  • Windows launches the app through a Search or Share Target contract.
  • Windows invokes a protocol (URI scheme) association (bit.ly/QyzX04) or launches an app due to a file association.
  • Windows invokes an extension, such as a File Open Picker contract or Contact Picker.

How activation occurs determines what code needs to run. Launches from a tile, contract or protocol cause a Windows Library for JavaScript (WinJS) app to fire an activated event and a XAML app to fire an OnLaunched event. During these events, you check the app’s previous state to take appropriate actions. 

If the app is moving from a not-running state to a running state, you need to load fresh data, as this transition indicates the app launch came from a tile, charm, protocol or extension. If the app is returning from a suspended state, you generally need to do nothing; the user can just pick up where he left off. If the app is moving from a terminated state to a running state, you need to reload the data and navigate in the app to the last place the user was (unless it has been months since the last use). Code to handle activation is shown in JavaScript in Figure 2 and in C# in Figure 3. As the code shows, you can test for the previous execution state as well as how Windows launched the app, because the Windows API has a handy set of enumerations for both cases. Once you have that information, you can repopulate the data as needed.

Both the JavaScript activated and XAML OnLaunched events contain an args argument you can query to determine the state the app was in prior to activation. Figure 2 and Figure 3 show examples of the activated event.

Figure 2 JavaScript App-Activation Code

var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
app.addEventListener("activated", function (args) {
  if (args.detail.kind === activation.ActivationKind.launch) {
    if (args.detail.previousExecutionState !==
      activation.ApplicationExecutionState.terminated) {
      // TODO: This application has been newly launched.
      // Initialize your application here.
    } else {
      // TODO: This application has been reactivated from suspension.
      // Restore application state here.
    }
    if (app.sessionState.history) {
        nav.history = app.sessionState.history;
    }
    args.setPromise(WinJS.UI.processAll().then(function () {
      if (nav.location) {
          nav.history.current.initialPlaceholder = true;
          return nav.navigate(nav.location, nav.state);
      } else {
        return nav.navigate(Application.navigator.home);
      }
    }));
  }
});

Figure 3 C# App-Activation Code

async protected override void OnLaunched(LaunchActivatedEventArgs args)
  {
// Check whether the session data should be restored.
    if (args.PreviousExecutionState == 
      ApplicationExecutionState.Terminated)
    {
      // Here we've created a SuspensionManager class that
      // handles restoring session data from a file and
      // then gives access to that data through a Dictionary.
      await SuspensionManager.RestoreAsync();
// Retrieve the data for restore.                 
data = SuspensionManager.SessionState["savedData"];
    }
    // If not, use the app's default values
    else
            {
data = "Welcome";
    }
    Window.Current.Activate();
}

Code that runs during activation must run within 15 seconds or Windows will terminate the app. Though this may seem strict, apps that block the user from interacting with the UI for that long aren’t responsive. According to UseIt.com research on users and response times (bit.ly/NWSumy), most users abandon Web sites that take more than 10 seconds to load. In fact, users become frustrated when pages take more than 1 or 2 seconds to load, and many leave far before the 10-second benchmark. Knowing this about users is especially important if you plan to sell your app in the Windows Store, because frustrated users post negative app reviews—not to mention that your app might not even pass store certification if it performs poorly. (See bit.ly/OxuEfu for more information on submitting an app.) It’s important to carefully consider what data to load and when. Fortunately, the Windows Runtime (WinRT) libraries make it easy to load data quickly and progressively by offering a first-class asynchronous programming model (bit.ly/NCx6gE).

The Windows.ApplicationModel.Activation object is part of the Windows API accessible by all Windows Store apps, regardless of language. The Activation object contains an activationKind enumeration with the following values:

  • Launch: The user launched the app or tapped a secondary tile.
  • Search: The user wants to search with the app.
  • ShareTarget: The app is activated as a target for share operations.
  • File: An app launched a file whose file type this app is registered to handle.
  • Protocol: An app launched a URL whose protocol this app is registered to handle.
  • FileOpenPicker: The user wants to pick files or folders provided by the app.
  • FileSavePicker: The user wants to save a file and selected the app as the location.
  • CachedFileUpdater: The user wants to save a file for which the app provides content management.
  • ContactPicker: The user wants to pick contacts.
  • Device: The app handles AutoPlay.
  • PrintTaskSettings: The app handles print tasks.
  • CameraSettings: The app captures photos or video from an attached camera.

Because your app might support multiple features, such as both share and search, the activationKind enumeration allows you to see what the user’s intent is for launching the app, and then to execute corresponding code.

Managing Suspension, Termination and Resume

When a user switches to a different app, or the device hibernates or goes to sleep, Windows stops the app code from running, yet keeps the app in memory. The reason for this suspension is that it minimizes the battery and performance impact of apps the user is not actively getting value from. When Windows wakes up the app from suspension or a short termination, the user should feel as if the app had never stopped running. Proper handling of lifecycle events ensures a responsive design.

Windows starts the suspension process by raising either a WinJS oncheckpoint event or a XAML OnSuspending event where you can save data and user information before the app moves into suspended mode. Any code you run in these events must complete within 10 seconds or Windows stops the app completely. Just as with the activation process, this rule keeps the overall health of the OS stable and enables fast switching. Hooking into the oncheckpoint event requires a simple function definition:

app.oncheckpoint = function (args) {
  // Save app data in case of termination.
};

In XAML, you use an Application.Suspending event:

async void Suspending(Object sender,
  Windows.ApplicationModel.SuspendingEventArgs e) {
  // Save app data in case of termination.
}

During suspension you need to save the user’s location or scroll position in the app, release file handles and connections, and date- and time-stamp the data. You can accomplish this using the built-in WinJS.Application.sessionState or XAML SuspensionManager objects. You should always save user information and app data in the suspending event because Windows doesn’t notify apps before it terminates them. This is important because termination can occur under a variety of circumstances, such as when Windows needs to free memory or the device loses (battery) power.

So code defensively and assume the app will terminate. This means you should save app data to sessionState every time. If Windows does terminate the app, the data is saved and ready for repopulation.

Resume occurs when Windows wakes up an app from suspension. Most of the time, Windows will simply resume your app when the user switches back to it or re-launches it, and code-wise you need to do nothing. During suspension the app just sits in memory, untouched, so the app content remains unchanged and there’s no need to take any action.

While most apps won’t need to do any work upon resuming from a suspended state, apps that contain frequently changing data—such as RSS feeds, stocks or social networking—are good candidates for using the resuming event. Because the resuming event fits these few specific scenarios, it lives in the Windows.UI.WebUI.WebUIApplication object rather than in the more common WinJS.Application object, alongside the oncheckpoint, onactivated and other sibling lifecycle events:

Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", function () {
  // Repopulate data from sessionState.
});

You can add the resume handler to the default.js file near the activation code for code-organization purposes. Keep your app responsive by quickly loading just the minimal amount of data while resuming.

Background Tasks and Real-Time Communications Apps

Although the UI code doesn’t run while an app is in suspended mode, an app can perform background tasks (bit.ly/QyRvsU), transfer large files or check for e-mail. Some real-time communications apps, such as IM clients, need to be able to notify the user when a message arrives, regardless of the app execution state.

Background tasks are lightweight classes that run periodically, under certain restrictions, while the app is technically not running. They run in their own sandboxes or app containers while the app remains in a not-running state. JavaScript background tasks run in a new single-threaded apartment of WWAHost.exe, and non-JavaScript background tasks run in an in-process .dll loaded into its own threading apartment in the app. This separation allows background tasks to run independently of an app’s UI, which remains suspended until the user returns to the app.

In addition to being able to execute code in the background, these apps also display information on the lock screen. The lock screen contains a background image with lightweight information superimposed on it, such as time, date, battery status and network status. In addition, apps—specifically apps that are running in the background—can display information on the lock screen. Because it’s important to keep the lock screen easily digestible, the information that can be displayed is limited. Badges from up to seven apps can be displayed, and the text from a single app’s tile can be shown on the lock screen. For more information, see the lock screen overview at bit.ly/RsE7pj.

Follow the Model

As a developer of Windows Store apps, you need to be concerned with issues such as battery life and memory pressure, running your app on a variety of devices and, most important, the UX. You’ll find your goals easier to achieve if you follow the prescribed lifecycle management guidelines. Moreover, besides the technical reasons for app lifecycle management, if your app is highly responsive and performs well, it will get better reviews in the Windows Store.


Rachel Appel is a developer evangelist at Microsoft New York City. Reach her via her Web site at rachelappel.com or by e-mail at rachel.appel@microsoft.com. You can also follow her latest updates on Twitter at twitter.com/rachelappel.

Thanks to the following technical experts for reviewing this article: Adam Barrus, Ben Betz, Arun Kishan, Michael Krause, Hari Pulapaka, John Sheehan and Ben Srour