[Update 12/31/2012: See also this post for a new Windows Phone 8 API to terminate apps]
[Update 7/27: fixed a typo and made it a bit clearer; thanks Nicole! Also added a link to code with the new Mango APIs]
I have previously blogged about exiting a Windows Phone application but a further post is needed due to a disturbing trend we're seeing in the marketplace: more and more applications are choosing to throw an unhandled exception in order to exit themselves.
There appear to be several reasons for this:
- The application has some kind of consent screen and if the user says "No" they want to quit
- The application has a complex navigation system and the only way to quit when hitting the Back key is to force-quit
- The application receives an error response from a webservice and doesn't want to handle it
- The application really wants an "Exit" button
The recommended way to handle #1 is covered in the previous post: just omit the "No" button and the user will figure out that pressing the Start or Back buttons both have the desired result of removinf the application from the screen.
The recommended way to handle #2 for most applications is covered in my places post (now on MSDN): when used correctly, page-based navigations will enable the user to back out naturally. For some applications that have a strong focus on "browsing" content - like the IMDb or Amazon applications, for example - the "places" concept doesn't really fit, and Yochay has published a recipe for a non-linear navigation service that should handle most cases of returning correctly to a home screen such that the Back button naturally exits your application.
The recommended way to handle #3 is to deal with the failure and let the user know something went wrong. Exceptions are meant for "exceptional" (ie, unexpected) situations, and having a web service call return an error code is not an unexpected situation. It is a terrible user experience to be interacting with an application and then suddenly see it disappear and be dumped unceremoniously at the Start menu. Obviously we don't want applications showing the HTTP error code to the user, but a simple piece of UX like "request failed; try again?" would suffice. Even if your app is totally unusable without the web service connection, you can at least show some UX along the lines of "we can't connect right now; try again later" and leave it to the user to hit Back or Start.
The recommended way to handle #4 is to embrace the Windows Phone UX and realize that an Exit button is superfluous. One explanation for why developers want to have an Exit option goes along the lines of this:
The phone has limited resources. If the user is done with my app, I want to be a good citizen and stop using resources. On other platforms (Windows Mobile, Windows Desktop, some other mobile OSes) simply switching away from an application doesn't kill it. Therefore I will let the user completely exit my app to ensure I don't use their phone's resources.
The thing is, on Windows Phone 7 the OS does take care of deactivating your application so that it can't use precious resources like CPU, memory, or battery. If the user hits Start to begin another task, your app is gone and can't possibly affect the user experience; there is no need to explicitly exit it. Furthermore, if some applications start having Exit buttons and others don't, there is a fear that customers will start to look for exit buttons everywhere. The logic goes something like this:
- This app has an Exit button
- I know I can just hit the power button to put the phone to sleep, or hit the Start to go to another app, so the Exit button must be there for a reason
- The reason is probably that the app will drain my battery if I don't exit it (based on past experience, urban legend, etc.)
- I'd better start exiting all my apps to ensure my battery doesn't drain too fast
- Oh my goodness, most apps don't have Exit buttons
We don't want to burden our users with the fear of wasting resources and the need to exit apps; we just want them to love using the phone. Putting an Exit button in your app just confuses users and reduces their overall satisfaction with the phone. That's the theory, anyway :-).
Another problem with deliberately crashing your application (vs. relying on the user to hit Start) is that the application will be removed from the back stack, breaking the user's expectation that they can return to it using the Back button. This will only get worse in the future, as users will expect recently-used applications to be in the application-switching UI (as demoed at Mobile World Congress), but applications that crash due to an unhandled exception won't appear in that list.
The Application Certification Requirements have two things to say on this topic.
Firstly, requirement 5.2.4(a) states:
Pressing the Back button from the first screen of an application must exit the application
This is most likely what drives #2 above - the app needs to pass certification testing, but due to their complex back stack the Back button doesn't actually exit the app. Ideally the requirement would add "...without resorting to throwing an exception" to make it clear this should happen naturally, but currently it doesn't. Fixing the navigation pattern will let you pass certification without throwing exceptions.
Secondly, requirement 5.1.2 states:
The application must handle exceptions raised by the .NET Framework and not terminate unexpectedly. [...] An application that terminates unexpectedly fails certification.
This requirement is enforced for normal application usage - if the application crashes randomly during testing, it will fail - but is not currently being tested for the exit case because in some ways the termination is not "unexpected" - the user pressed Back and the app disappeared. Nevertheless, this is not the spirit of the requirement and you shouldn't take advantage of it.
Requirement 5.1.2 also states:
When handling exceptions, an application must provide a user-friendly error message. You may present a message that is relevant to the context of the application. The application must continue to run and remain responsive to user input after the exception is handled.
This clearly shows that scenario #3 above (exiting when an exception is received) violates the certification requirements and should not happen.
The current situation isn't ideal - we have an API set that doesn't meet everyone's needs (although Yochay's sample goes a long way to solving many problems) and we have certification requirements that aren't crystal clear (or always enforced). Obviously I can't promise you anything about future updates, but we are thinking about these things and trying to improve them at all levels (APIs, certification, documentation, etc.). Your best bet is probably to wait for Mix '11 in April, but other than the keynote nothing has been announced yet so don't hold your breath for Joe Belfiore to mention exit buttons on-stage ;-).
I can now revearl that there are some new APIs in Mango to specifically deal with his - see my post on Alarms and Notifications for some sample code for dealing with "interesting" navigation scenarios.
What about XNA?
An observant developer might point out that XNA applications on the phone do have access to an Exit method, so doesn't that invalidate everything I said above? Yes and no: Yes, XNA applications can exit themselves; No, XNA applications can't not exit themselves (with apologies to Jack Donaghy). But seriously, this is more about compatibility with the other XNA platforms (Windows and Xbox) that use the Back button on a controller to show menus or exit. Additionally, the only game I have seen that actually uses this feature is Tetris; that's not to say other games don't use it, but it's clearly not used universally by XNA applications.
Feel free to add a comment below (or send me a private mail) if you have other reasons for needing to exit your application; please be as descriptive as possible as to what your intended UX is and why you can't build that with the current API set. All feedback is helpful!
Thanks to Steve Bell and other Windows Phone folks for their input on this blog post.