One of the questions every developer must face when a new technology like WP7 comes on the scene is whether to jump onboard early (in the CTP and Beta stages) or wait until a platform RTMs. The advantage of the former is that one has a longer lead time to learn the technology and establish oneself as an authority on the technology inside one’s company or on the web. The advantage of the latter is that one doesn’t waste time learning things about the technology that are in flux and may go away; instead one can wait for the experts to say what they have to say and learn from that.
A possible advantage to deferring the groking of a new technology is that one also has less to unlearn. Early adopters often make the mistake of assuming that they do not have to re-examine what they already know when the technology RTMs. The problem for those who defer learning new technologies is that, if they are not careful, they may inherit the bad information disseminated by those early adopters and insiders, and suddenly we are all stuck in a situation where what counts as common knowledge is simply wrong.
Probably the worst case of this for Windows Phone developers occurred with launchers and choosers. The original metaphor seemed clear enough: launchers are fire-and-forget components, choosers return information. This turns out not to be completely true, however. Save operations, which are considered launchers, must return information about whether each save was successful. They aren’t really fire-and-forget.
Another early lesson WP7 developers learned was that all launchers and choosers cause an application to tombstone – and thus was created one of the most obscure and difficult aspects of Windows Phone development. As WP7 went from Beta to RTM, however, it was decided that this didn’t always make sense. Recovering from tombstoning is time-consuming. Why force an app to tombstone for something like the CameraCaptureTask when the user will most likely return to the application immediately after the task is completed? To find out more about deferred tombstoning, see Why Deactivated is Not the Same as Tombstoning.
Just to make things a little more complicated, it isn’t just the four choosers which turn out to not force tombstoning. MediaPlayerLauncher, one of the eleven launchers, also implements deferred tombstoning. The PhoneCallTask also does not throw an application into tombstoning mode (additionally, it also never seems to trigger the Deactivated event). Incoming phone calls, outgoing phone calls, the five choosers and MediaPlayerLauncher all merely suspend (or pause) the application, keeping all the pages along with their state in memory.
If you are confused, welcome to the club. The original metaphor of having launchers and choosers broke down bit by bit through subsequent iterations of the Windows Phone platform. Experts quote each other based on these different iterations. After a while, no one is sure anymore exactly how launchers and choosers work.
The solution, naturally, is to trust but verify everything you read. You can find out whether an application is actually tombstoned when a task (the generic name for both launchers and choosers) is initiated by placing a simple debug message in the constructor of the page that launches the task. If the constructor is called when you press back from the task, then your application was tombstoned. If the constructor is not called, then you know the page has been retained in memory and tombstoning did not occur.
Once you have verified something like this, always write it down somewhere. Here’s the chart I keep for myself to help remember the behavior of various launchers and choosers. It is for the RTM version of Windows Phone only. Please take it with a grain of salt.
Task |
Launcher |
Chooser |
Returns Data |
Defers Tombstoning |
Suspends Application |
CameraCaptureTask |
X |
X |
X |
X |
|
EmailAddressChooserTask |
X |
X |
X |
X |
|
EmailComposeTask |
X |
||||
MarketplaceDetailTask |
X |
||||
MarketplaceHubTask |
X |
||||
MarketplaceReviewTask |
X |
||||
MarketplaceSearchTask |
X |
||||
MediaPlayerLauncher |
X |
X |
X |
||
PhoneCallTask |
X |
X |
|||
PhoneNumberChooserTask |
X |
X |
X |
X |
|
PhotoChooserTask |
X |
X |
X |
X |
|
SaveEmailAddressTask |
X |
X |
|||
SavePhoneNumberTask |
X |
||||
SearchTask |
X |
||||
SmsComposeTask |
X |
||||
WebBrowserTask |
X |