Tag: Tombstoning

MessageBox, Navigation and Application Life Cycle

One of our applications failed certification today because of an issue I should have known about. Even though the scenario in which an exception occurs is fairly easy, solving the problem properly involves a little work and a little thinking. Other blog entries have been written about this particular problem, although suggested solutions did not seem to work for me. Let me first show the original code:

MessageBox and Navigation
  1. private void TurnCard_Click(object sender, System.Windows.RoutedEventArgs e)
  2. {
  3.     MessageBoxResult mr = MessageBoxResult.Cancel;
  4.  
  5.     if (nrTimesClicked > 2)
  6.     {
  7.         mr = MessageBox.Show("Continuing now might confuse you. Try again tomorrow?",
  8.             "Continuing tomorrow?", MessageBoxButton.OKCancel);
  9.     }
  10.  
  11.     if (mr == MessageBoxResult.OK)
  12.     {
  13.         NavigationService.GoBack();
  14.     }
  15.     else
  16.     {
  17.         Random r = new Random();
  18.         int card = r.Next(cardPages.Length);
  19.         NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
  20.         nrTimesClicked++;
  21.     }
  22. }

Running this code and clicking the Start button on the phone while the MessageBox is visible results in the following exception when running with the debugger attached (it results in an application termination when running stand-alone):

image

The NavigationFailed event is raised. This is caused by the fact that the MessageBox returns when clicking the phone’s Start button with a return value of MessageBoxResult.Cancel. Since in the above code fragment, the Cancel button is used to navigate to some page, even though the application is supposed to go to the background in order to display the start screen on the phone, navigation fails. The interesting part is that the application does not have a clue that the user pressed the Start button on the phone. So some thinking is required to fix this issue.

Single stepping through the problematic method TurnCard_Click showed another behavior:

image

This at least made clear that indeed the call to the NavigationService caused the problem. To solve the problem, what can be done is protecting calls to the NavigationService by catching this particular exception:

Protecting the Navigate method
  1. private void TurnCard_Click(object sender, System.Windows.RoutedEventArgs e)
  2. {
  3.     MessageBoxResult mr = MessageBoxResult.Cancel;
  4.  
  5.     if (nrTimesClicked > 2)
  6.     {
  7.         mr = MessageBox.Show("Continuing now might confuse you. Try again tomorrow?",
  8.             "Continuing tomorrow?", MessageBoxButton.OKCancel);
  9.     }
  10.  
  11.     if (mr == MessageBoxResult.OK)
  12.     {
  13.         NavigationService.GoBack();
  14.     }
  15.     else
  16.     {
  17.         Random r = new Random();
  18.         int card = r.Next(cardPages.Length);
  19.         try
  20.         {
  21.             NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
  22.         }
  23.         catch (InvalidOperationException)
  24.         {
  25.             ;
  26.         }
  27.         nrTimesClicked++;
  28.     }
  29. }

This does solve the problem, although I don’t like it that an exception is thrown in a situation that the operating system should somehow prevent us against (maybe by returning some other value when the MessageBox returns without the user clicking on one of its buttons). If you want to have a little more flexibility, and don’t mind coding a bit more, there is another possible solution. Instead of using a MessageBox, you can make use of the Guide.BeginShowMessageBox method that is defined in the XNA Framework. This method is a bit more complex, but also much more flexible then its Silverlight counterpart. BeginShowMessageBox is asynchronous, which means that you need to take care with calling code that is supposed to run on the UI Thread.

Using BeginShowMessageBox
  1. private void TurnCard_Click(object sender, System.Windows.RoutedEventArgs e)
  2. {
  3.     if (nrTimesClicked > 2)
  4.     {
  5.         ShowContinueMessage();
  6.     }
  7.     else
  8.     {
  9.         Random r = new Random();
  10.         int card = r.Next(cardPages.Length);
  11.         nrTimesClicked++;
  12.         NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
  13.     }
  14. }
  15.  
  16. private void ShowContinueMessage()
  17. {
  18.     List<string> mbOptions = new List<string>();
  19.     mbOptions.Add("OK");
  20.     mbOptions.Add("Cancel");
  21.     string msg = "Continuing now might confuse you. Try again tomorrow?";
  22.     string title = "Continuing tomorrow?";
  23.     Guide.BeginShowMessageBox(title, msg, mbOptions, 0, MessageBoxIcon.Alert, EnteredAnswer, null);
  24.     messageBoxVisible = true;
  25. }
  26.  
  27. private void EnteredAnswer(IAsyncResult ar)
  28. {
  29.     int? result = Guide.EndShowMessageBox(ar);
  30.  
  31.     if (result != null)
  32.     {
  33.         messageBoxVisible = false;
  34.     }
  35.  
  36.     if (result != null && result == 0)
  37.     {
  38.         this.Dispatcher.BeginInvoke(delegate
  39.         {
  40.             NavigationService.GoBack();
  41.         });
  42.     }
  43.     else if (result != null)
  44.     {
  45.         Random r = new Random();
  46.         int card = r.Next(cardPages.Length);
  47.         this.Dispatcher.BeginInvoke(delegate
  48.         {
  49.             NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
  50.         });
  51.     }
  52. }

The interesting code can be found in the EnteredAnswer method, where we retrieve the key the user entered in the message box. Since EndShowMessageBox returns a nullable integer, it has this nice way of using null in those cases where the user did not click any key (in other words, for instance when the message box is removed as a result of the application going to the background). So now we have a way of detecting if we can navigate (result has a value other then null). The sample code also sets a boolean variable messageBoxVisible, which is used in combination with PhoneApplicationPage.State to display the message box again when the user returns to the application. Hopefully this time the application will pass certification.

EvenTiles from Start to Finish–Part 8

In the previous episode of this series about how to develop a Windows Phone application from scratch we talked about Fast Application Switching and Tombstoning. We saw how Visual Studio 2010 can help us testing Tombstoning scenarios. We also covered how to preserve application data when the application is interrupted by other applications and how to restore that data when returning to the foreground.

Right now we will extend our knowledge about Fast Application Switching and Tombstoning by trying to exactly restore a page after the application returns from the background. For that, we will take a look at the following scenario.

imageThe user is entering data in the textbox inside the SettingsPage. This means that a keyboard is visible and that the textbox has input focus and a blinking cursor at the location where data is entered. Sometime in the middle of entering text, the user hits the start button to activate another application, to return to our application only after a while. Even though we have stored all data the user entered (because we are saving the contents of the textbox when navigating away from the SettingsPage), the text box does not have focus when the user returns to the SettingsPage, nor a cursor positioned at the right location. In order to restore the exact same situation, we need to store additional data when navigating away from the SettingsPage. This leads to another challenge. To store the local page state when we are navigating away from the SettingsPage we can use the following code:

Saving the Page State
  1. protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
  2. {
  3.     if (!e.IsNavigationInitiator)
  4.     {
  5.         TextBox tb = FocusManager.GetFocusedElement() as TextBox;
  6.  
  7.         if (tb != null)
  8.         {
  9.             this.State[keySelectionLength] = tb.SelectionLength;
  10.             this.State[keySelectionStart] = tb.SelectionStart;
  11.         }
  12.     }
  13.     App.ActualSecBackContent = tbBackContent.Text;
  14.     base.OnNavigatedFrom(e);
  15. }

Each time OnNavigatedFrom is called, there is a possibility that the application is moved to the background. If so, the property IsNavigationInitiator is false. If the application is moved to the background, we check if the textbox currently has focus. If so, we will store the location of the cursor by adding entries for both the SelectionStart (location where the cursor is) and SelectionLength. If on the other hand the textbox does not have focus, we don’t have to store page state information, just the Text property of the textbox.

Retrieving page state information back can be done in the OnNavigatedTo method as follows:

Restore the Page State
  1. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  2. {
  3.     tbBackContent.Text = App.ActualSecBackContent;
  4.     btnRestore.Visibility = tbBackContent.Text.Equals(App.DefaultSecBackContent) ?
  5.         System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
  6.  
  7.     if (this.State.ContainsKey(keySelectionLength))
  8.     {
  9.         tbBackContent.SelectionLength = (int)this.State[keySelectionLength];
  10.         tbBackContent.SelectionStart = (int)this.State[keySelectionStart];
  11.         focusToTextBox = true;
  12.     }
  13.     base.OnNavigatedTo(e);
  14. }

However, it is not possible to get the focus back to the textbox control in the OnNavigatedTo method, because the different UI elements are not yet initialized when OnNavigatedTo is called. That is the reason to set a boolean variable to true and actually give the textbox focus when the Loaded event on the page is fired. If the application is returning from the background and focusToTextBox is set to true, the tbBackContent textbox will get focus:

Restore textbox input focus
  1. private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
  2. {
  3.     if (focusToTextBox)
  4.     {
  5.         tbBackContent.Focus();
  6.     }
  7. }

If an application would always be tombstoned, this would be sufficient to store / restore state information for the page and to restore the input focus if the textbox had focus when the application was put in the background. However, with Windows Phone Mango, applications can benefit from the Dormant state, where they stay in memory even though being in the background. There is not really a clear distinction from a developer’s point of view between Dormant and Tombstoned, except for the fact that in case of returning from being Tombstoned, the page constructor is executed, something that is not the case when the application returns from Dormant since the application was still in memory. As a consequence, returning from the Dormant state also means that the Loaded event on the page is not fired. So, even though returning to the foreground is faster if we were in the Dormant state, we need some additional logic to give the textbox focus in this case. In order to distinguish between Dormant and Tombstoned, it is possible to set a boolean variable in the constructor of a page to true and check that variable in the OnNavigatedTo method:

Dormant vs Tombstoned
  1. private bool focusToTextBox;
  2. private bool pageConstructed;
  3.  
  4. public SettingsPage()
  5. {
  6.     InitializeComponent();
  7.     pageConstructed = true;
  8. }

The value of the pageConstructed variable determines if we are returning from a Dormant state to the foreground (false) or not. If we are not returning from a Dormant state, we need to determine in OnNavigatedTo if we returned from a Tombstoned state in order to optionally set the focus to the textbox. However, if we are returning from a Dormant situation, the OnNavigatedTo method itself must be used to set focus to the textbox if needed. The modified OnNavigatedTo method looks like this:

Complete Page Reconstruction
  1. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  2. {
  3.     tbBackContent.Text = App.ActualSecBackContent;
  4.     btnRestore.Visibility = tbBackContent.Text.Equals(App.DefaultSecBackContent) ?
  5.         System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
  6.  
  7.     if (this.State.ContainsKey(keySelectionLength))
  8.     {
  9.         tbBackContent.SelectionLength = (int)this.State[keySelectionLength];
  10.         tbBackContent.SelectionStart = (int)this.State[keySelectionStart];
  11.         if (!pageConstructed)
  12.         {
  13.             tbBackContent.Focus();
  14.         }
  15.         else
  16.         {
  17.             focusToTextBox = true;
  18.         }
  19.     }
  20.     base.OnNavigatedTo(e);
  21. }

The following video shows how to save and restore the page state for the SettingsPage of EvenTiles for the different application execution states:

Saving Page State and restoring Textbox Focus

Update after video creation: Even though it seems in the video that the application is working properly both when returning from Dormant and from Tombstoning states, this is not entirely the case. Even though the focus of the Textbox is restored properly when needed, the Textbox will also get focus each and every time we return from the background, with the exception of the first time. The reason for that is that the dictionary entries in the Page.State collection were not deleted after usages in the OnNavigatedTo method. The source code for EvenTiles contains a fix for this undocumented application feature.

If you want to take a look at the source code that we have available for EvenTiles so far, you can download the entire solution belonging to this episode:

Download EvenTiles Episode 8 Source Code

After downloading and unzipping the sample code, you can open the EvenTiles solution in Visual Studio 2010 Express for Windows Phone. You must have the Windows Phone SDK 7.1 installed on your development system to do so. If you have a developer unlocked phone you can deploy the application to your phone, if you don’t have a developer unlocked phone you can still experiment with this application inside the emulator.

In the next episode of EvenTiles we will finally get to the heart and soul of the application, when we are going to create a Secondary Tile.

EvenTiles from Start to Finish–Part 7

In the previous episode of this series about how to develop a Windows Phone application from scratch we used the Isolated Storage Explorer Tool to take a look at the contents of the ApplicationSettings, stored in IsolatedStorage on the device or emulator. This time we continue dealing with our application settings, because we are going to talk about Fast Application Switching and Tombstoning.

As you probably know, only one application can be running in the foreground on a Windows Phone. That application can use as much resources as it needs and should be as responsive as possible to give end users a great experience. Typically, users switch often between applications. They might not even think about different applications, because they are most likely very task oriented. To give end users the best experience, our applications share a responsibility with other applications and with the operating system.

If our application is currently running in the foreground, there are two important reasons for our application to stop running in the foreground:

  1. The user terminates our application by pressing the Back Key on the phone until the entire back stack of pages for our application is empty.
  2. Our application is interrupted because some sort of an event occurred.

The first situation is simple. When our application is terminating, it is our responsibility to store information that we want to persist until the next time our application is running. This is what we did for EvenTiles in part 5 of the series, using the Application_Launching and Application_Closing methods that are defined in the App.xaml.cs file.

NOTE: The description of Fast Application Switching and Tombstoning in this article is valid for Windows Phone Mango, not for previous versions of the operating system.

The following picture shows our application running over time. The user navigated to the SettingsPage on EvenTiles, modified the string value and decided to use the Start Key on the phone to start another application. After a while, the user returns to our application by pressing the Back Key until our SettingsPage is visible again.

image

For the user, this experience is great, because when they come back to our application, it shows up exactly as it was when they moved our application to the background. The operating system simply keeps our application in memory. There are some restrictions with regards to applications using certain resources like the camera. To keep our story lean and mean we will omit those. When the user starts many applications (thus putting more and more applications in the background), at some time the amount of available memory gets so low that another application can no longer be started. In this situation, the operating system decides to remove the oldest application in the background from memory, saving just minimal state information for that application. In this situation, the application that was just removed from memory is said to be Tombstoned. To restore our application from being tombstoned, we not only need to reload our application settings (as we did on the Application_Launching event), but most likely we also need to restore additional data. The Operating System ‘remembers’ the page in our application the user had visible when we were tombstoned. It is our responsibility to restore data that the user entered on that page (for instance the contents of a Textbox).

When our application is send to the background, several things happen. On the page that is currently visible, an OnNavigatedFrom event will occur. Also, the Application_Deactivated method in the App.xaml.cs file will be called. When an application is switched to the background, basically three things can happen to it:

  1. The application will become the foreground application again without having entered the tombstone state. In this situation the application can benefit from Fast Application Switching.
  2. The application got tombstoned, but it will become the foreground application after a while. In this situation the application must restore more state information.
  3. The user starts the application again by clicking its icon or tile on the start screen. In this situation, the previous instance of the application is removed and the user should see the application in its initial state.

dump3When you are debugging your application in Visual Studio, the default behavior when the application is moved to the background is for it to remain in memory. However, by modifying one of the project properties (as shown in the screen dump on the left), you can force the application to become tombstoned, regardless from the amount of free memory on the device (emulator). In this way, we as developers have the possibility to test our applications in either state they enter when being moved to the background. You should make sure that you test the tombstone scenario for your application. For instance, if EvenTiles with its current functionality is tested for tombstoning it will crash. This currently has to do with the way that data is initialized. In EvenTiles, we have a string property defined in App.xaml.cs that will later be used to write information to the back side of our Secondary Tile. The SettingsPage already makes use of this property. However, we are initializing this property, named ActualBackSecContent when the application is started in the Application_Launching method.

Activating and Terminating
  1. // Code to execute when the application is launching (eg, from Start)
  2. // This code will not execute when the application is reactivated
  3. private void Application_Launching(object sender, LaunchingEventArgs e)
  4. {
  5.     if (!appSettings.Contains(keyActSecBackContent))
  6.     {
  7.         appSettings[keyActSecBackContent] = DefaultSecBackContent;
  8.     }
  9.     ActualSecBackContent = (string)appSettings[keyActSecBackContent];
  10. }
  11.  
  12. // Code to execute when the application is activated (brought to foreground)
  13. // This code will not execute when the application is first launched
  14. private void Application_Activated(object sender, ActivatedEventArgs e)
  15. {
  16. }
  17.  
  18. // Code to execute when the application is deactivated (sent to background)
  19. // This code will not execute when the application is closing
  20. private void Application_Deactivated(object sender, DeactivatedEventArgs e)
  21. {
  22. }
  23.  
  24. // Code to execute when the application is closing (eg, user hit Back)
  25. // This code will not execute when the application is deactivated
  26. private void Application_Closing(object sender, ClosingEventArgs e)
  27. {
  28.     appSettings[keyActSecBackContent] = ActualSecBackContent;
  29. }

Even though our application is removed from memory when it is tombstoned, if the user navigates through the back stack using the back key on the phone, eventually they will return back to a page of our application. In order to make this happen in case our application was tombstoned, it has to be reloaded again to memory to become active. In this situation, minimal state information was stored by the imageoperating system (for instance which page was the last page the user saw when our application got tombstoned). On returning from tombstoning we will return to that page, but since the application needs to be started completely, classes have to be newly created and code in constructors of those classes will therefor be executed. To distinguish between starting a fresh copy of the application or returning from the background, Application_Launching (fresh restart) or Application_Activated (tombstoning or fast application switching) is called in our App.xaml.cs file. If our application was still in memory, there is no problem, after all, the property ActualSecBackContent still holds its value. If we are returning from a tombstoning situation we do have a problem, since Application_Activated will be called instead of Application_Launching. That is why the exception that is shown in the screen dump above was thrown.

You might think that this problem could easily be solved by initializing the ActualSecBackContent property in the constructor of our App class, but that would mean that we don’t benefit from fast application switching (the situation where our application remains in memory, even though it is in the background). A better solution is to make use of the Application_Activated event as follows:

Switching between BG and FG
  1. // Code to execute when the application is activated (brought to foreground)
  2. // This code will not execute when the application is first launched
  3. private void Application_Activated(object sender, ActivatedEventArgs e)
  4. {
  5.     if (!e.IsApplicationInstancePreserved)
  6.     {
  7.         // The application was not preserved in memory, so we were tombstoned
  8.         // Only in this case we need to re-initialize ActualSecBackContent
  9.         ActualSecBackContent = (string)appSettings[keyActSecBackContent];
  10.     }
  11. }
  12.  
  13. // Code to execute when the application is deactivated (sent to background)
  14. // This code will not execute when the application is closing
  15. private void Application_Deactivated(object sender, DeactivatedEventArgs e)
  16. {
  17.     appSettings[keyActSecBackContent] = ActualSecBackContent;
  18. }

If the application is becoming the foreground application, we check if we were still available in memory. If so (e.IsApplicationInstancePreserved == true) we don’t do anything, otherwise we just initialize the ActualSecBackContent property. There is nothing else to do, because we know that a value with that particular Settings key already is available, since the application was launched at some time before Application_Activated was called. If an application is moved to the background you want to make sure to save everything in such a way that you assume that your application will never return to the background. After all, the application can stay in memory, it might be tombstoned but there is also a possibility that the user starts a brand new instance of the application from the start menu. In the latter case, the existing instance of the application in the background will be removed by the operating system.

NOTE: If you are upgrading an existing application for Mango, at the very least (after converting your project in Visual Studio) you need to only retrieve stored data in the Application_Activated method when e.IsApplicationInstancePreserved is false. In that way your application will immediately benefit from fast application switching.

The following video shows the actions we took to prevent the EvenTiles application from crashing after being reactivated from a tombstoned state:

Fast Application Switching and Tombstoning (1)

With the changes that were described so far added to our application, it no longer crashes if we are returning from a tombstone state. There are however more things that need to be considered when the application is brought back from background to foreground. In the next Episode of EvenTiles we will take a look at restoring Focus on an input control when returning from the background.

If you want to see EvenTiles already in action on your Windows Phone, you can install the latest release from Marketplace. Remember that this application is not meant to be extremely useful, although it contains similar functionality that “serious” applications have. All functionality that you can find in the released version of EvenTiles will be covered in the upcoming episodes of this blog series, together with all source code. Just go ahead and get your free copy of EvenTiles from Marketplace at this location: http://www.windowsphone.com/en-US/search?q=EvenTiles (or search on your phone for EvenTiles in the Marketplace application).

Windows Phone Application Development & Debugging – Deactivation versus Tombstoning

While creating an update of an existing application I ran into a problem that sometimes occurred when the application was moved to the background. It turned out that the application behaved consistent with no exceptions raised when it was tombstoned after being moved to the background. However, the application sometimes crashed when it was deactivated and immediately became the executing application again without being tombstoned. In a later post I will explain the specific problem that caused the application to crash, for now I want to focus on ways to easily test deactivation scenarios.

Visual Studio 2010 has great support to test tombstoning scenarios for Windows Phone applications. Simply start debugging an application on a device or on device emulator and click the start button on the device (emulator). You will notice that the application moves to the background but that Visual Studio does not terminate its debugging session. Putting a breakpoint inside Activated / Deactivated event handlers shows us that the application is indeed being tombstoned / resurrected.

Visual Studio and Tombstoning

The debugger shows that the application is still running even though the application is no longer visible on the device. By using the back key on the device, it is possible to return to the application and to continue debugging it. However, if you start the application again on the device (so not using the back key), the debugger terminates. This means that a brand new instance of the application was started. Inside an application, it is possible to distinguish between a new instance being started and resurrection from being tombstoned by acting on the Launching or Activated events respectively. In both cases, the constructor of the page that becomes visible will be executed. More information about the application life cycle of a Windows Phone application can be found in this excellent series of blog entries by Yochay Kiriaty.

There are situations where an application is moved to the background without being tombstoned. In those situations, the application simply remains resident in memory, with its process being kept alive. When the application is activated again, it simply continues running without the need to create a new physical instance of the application. For end users the behavior is identical to tombstoning, after all, the application becomes invisible when another application starts executing. For developers there is a difference though, because no Launching or Activated event is raised and no constructor code (for instance for the currently visible page) is executed. To be able to consistently test application deactivation requires some additional work. One of the ways to ‘force’ deactivation over tombstoning is by starting a PhotoChooserTask. In my own application I simply use the application bar to add a new ApplicationBarIconButton to display a PhotoChooserTask.

To assure that this ApplicationBarIconButton is only visible in Debug mode, a bit of conditional compilation is needed. The following code snippet shows how to create a new ApplicationBarIconButton programmatically, add it to the ApplicationBar and add an event handler to its click event.

Adding an ApplicationBar Item
  1. #if DEBUG
  2. PhotoChooserTask _pt;
  3. #endif
  4.  
  5. public MainPage()
  6. {
  7.     InitializeComponent();
  8.  
  9. #if DEBUG
  10.     _pt = new PhotoChooserTask();
  11.  
  12.     this.ApplicationBar.IsVisible = true;
  13.  
  14.     ApplicationBarIconButton pauseButton = new ApplicationBarIconButton
  15.     {
  16.         Text = "Pause App",
  17.         IconUri = new Uri("/Images/appbar.transport.pause.rest.png", UriKind.Relative),
  18.         IsEnabled = true
  19.     };
  20.  
  21.     pauseButton.Click += new EventHandler(pauseButton_Click);
  22.     this.ApplicationBar.Buttons.Add(pauseButton);
  23. #endif
  24. }

Of course, adding a button to an existing ApplicationBar only works if the application has 3 or less ApplicationBarButtonIcons in use. An alternative could for instance be adding a MouseLeftButtonDown event handler to the application’s title. When clicking the ApplicationBarButtonIcon you created specifically for debug purposes, what you now can do is display the PictureChooserTask. This results in your application being pushed to the background, without being tombstoned.

Forcing us to the background
  1. void pauseButton_Click(object sender, EventArgs e)
  2. {
  3.     _pt.Show();
  4. }

This approach makes it relatively easy to test the different scenarios for your application going to the background and returning to the foreground again. Here are the results in a little test application.

TombstoningOrNot

In the left screen you can see the application immediately after the main page became visible. In the center screen you see the result of clicking the pause button, after which a PhotoChooserTask was activated and closed again. What you can see is that there is no Application_Deactivated / Application_Activated combination. You can also see that no constructor is called after returning from the PhotoChooserTask. In other words, the application is not tombstoned while the PhotoChooserTask is active. Finally, the right screen shows how the application returns from being tombstoned. In this case constructors are called and Application_Activated is raised.

The issue I had in one of my applications had to do with counting on constructors to be called to dynamically add a few controls to my visual tree.

Note: This blog entry is applicable for Windows Phone 7. For the next version of Windows Phone (codenamed Mango), developers can choose between tombstoning and fast application switching by setting the corresponding property in the project settings. Fast application switching could be considered as another state in the application’s life cycle, being very similar to the situation that was described in this post using the PhotoChooserTask.