次の方法で共有


This is not the exit you are looking for

[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:

  1. The application has some kind of consent screen and if the user says "No" they want to quit
  2. The application has a complex navigation system and the only way to quit when hitting the Back key is to force-quit
  3. The application receives an error response from a webservice and doesn't want to handle it
  4. 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:

  1. This app has an Exit button
  2. 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
  3. The reason is probably that the app will drain my battery if I don't exit it (based on past experience, urban legend, etc.)
  4. I'd better start exiting all my apps to ensure my battery doesn't drain too fast
  5. Oh my goodness, most apps don't have Exit buttons
  6. Panic!

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.

Certification Requirements

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.

Future Developments

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.

Feedback

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.

Comments

  • Anonymous
    February 24, 2011
    Unfortunately, I'd found many issues with the proposed Non-Circular recipe. Indeed created more issues than solving the,,,I know, that's unlucky. I still think that MS should stop thinking about NON including an App.exit (only when in the MainPage) then all issues will gone at once. Sometimes is better to hear what the community is saying- There is a reason for many apps to throw an exception...don't you think? IMHO, that's because the navigation pattern is, in many cases, a bad idea.

  • Anonymous
    February 24, 2011
    Thanks for the comment GFR. If you are "GFR2011" posting on Yochay's blog, the problem appears to be this: "P1, P2 and P3 have the BackKeyPress navigating to the specific page. (P3 to P2, P2 to P1, P1 to MainPage)" (quoted from windowsteamblog.com/.../solving-circular-navigation-in-windows-phone-silverlight-applications.aspx). BackKeyPress should never perform a forward navigation to a new page; you should just let it go back to the previous page. We do listen to developer feedback and, as I mentioned, we have spent a lot of time discussing this issue but our belief is that it is better for the end-user experience if the phone has a consistent model, and that model does not involve applications that exit themselves in a non-standard fashion.

  • Anonymous
    February 24, 2011
    The comment has been removed

  • Anonymous
    February 24, 2011
    The comment has been removed

  • Anonymous
    February 24, 2011
    Ah, thank you.  It makes sense that since I'm the one throwing a custom exception and not setting e.Handled = true in Application_UnhandledException that my approach is ok.  I simply don't want users to press the hardware back button and see the Splash page after the application loads and shows my MainVIew.  I'll consider changing my Splash UI to a popup on my MainView instead of a PhoneApplicationPage. There were interpretations (maybe from your older post) about how to exit like this one from James Ashley: www.imaginativeuniversal.com/.../How-to-Quit-a-WP7-Silverlight-Application.aspx

  • Anonymous
    February 24, 2011
    Actually it's not "OK" since it isn't an unrecoverable error; it's an artificial error you created. If you move your splash screen to be a popup then you don't need to do any of this - MainPage will be your first page and Back will naturally exit the application.

  • Anonymous
    February 27, 2011
    Hi Peter, I'm the same GFR2011, as you rightly pointed out. I'm also an 8-year MSFT veteran, so I really appreciate the hard work you guys are doing to make WP7 a great platform. Unfortunately, I still think that some exit mechanism, at least when in the MainPage and Bacl is pressed, must be included. I cannot see any trouble for this to be easily handled by the OS. I cannot also see any conflict of that with the notion of a consistent UX. However, I do see a great conflict with the UX for the current pattern. Let's face it. Screen factor is what drives our apps and their designs. If an app must resort to a multi-page nav, is in all probability to the need to split the logic/data among several pages, because there is no other way to cope the lack of screen space. It's indeed in the scenario I described (which is quite common) to have a very ugly UX, if the user when in P2, having just returned from P3 (where let's say he picked up a value from a ListBox) returns to P3 again (he wants to go back to P1), then again to P2...to then finally to P1. So, under the light of the UX (which is the most important factor), which scenario is right? BTW, these posts by you and the recipes, plus the app resorting to some weird mechanism, only speaks, at least to me, of a bad navigarion design or ... something that still needs some polishing. Maybe an EXIT mechanism? Well, thanks for listening to us. Just my 2 cents

  • Anonymous
    February 28, 2011
    Hi GFR, We did actually discuss allowing exit only if the backstack was empty (ie, you're on the first page) but then the user can just hit Back at that point (ie, no need for a button in the UX). I still don't understand your scenario of "if the user when in P2, having just returned from P3 (where let's say he picked up a value from a ListBox) returns to P3 again" - going from P3 to P2 should be a back navigation, and then hitting back again will go to P1 (and once more will exit). Also remember the Start button for the times when the user just wants to do something else. Or they can hit the power button if they are done. Please send me a mail (contact link above) if you want to discuss further

  • Anonymous
    February 28, 2011
    BTW, to the anonymous poster leaving MSS-related comments to this post, I'm not publishing them because they are not related to this post. Nevertheless, I have sent your feedback on to the appropriate people and if something interesting comes out of it I will post more.

  • Anonymous
    March 01, 2011
    The Game.Exit() method is absolutely required for XNA apps on WP7 because the Back button does nothing unless the game specifically checks for the Back button press and calls Game.Exit() when the game is on the main menu.  It is not just for compatibility with PC and Xbox 360.  Our Xbox LIVE games call Game.Exit, otherwise the user could never exit via the Back button.  To test this, create a new Windows Phone Game project and comment out the top two lines in Game1.Update().  Now launch the game and press the Back button.  Nothing happens.  Uncomment the two lines and launch the game again.  Press the Back button and the game exits as expected. I expect you will find a call to Game.Exit in all XNA games when the Back button is pressed on the main menu in order to satisfy the application certification requirement.  Well, some Xbox LIVE games will show an upsell screen first, but this upsell screen will then call Game.Exit() when it is done.

  • Anonymous
    March 01, 2011
    Steve, you are correct that XNA needs the Exit API given the way the platform works, but we could have used other mechanisms to enable Back to exit in XNA (eg, use "canel back key unless on first screen" logic). Compat with Xbox and Windows is the only reason it's really there.

  • Anonymous
    March 05, 2011
    The problem here is that there is no standard "screen", "page" or "navigation" known to XNA.  It has a Update and a Draw.  How the game implements the menus or game screens (XNA doesn't know the difference between menus or game either) is completely up to the developer. This is very different to Silverlight where pages and the stack are strongly enforced within the Silverlight framework, so unless you add menu or page classes and a standard navigation system to the XNA framework, I'm having trouble seeing how you could have made the Back button function "automatically" in XNA, so to speak.

  • Anonymous
    March 14, 2011
    I had a conversation with Peter on this, but feel it would be beneficial to post here my conclusions in case anyone else encounters the same scenario. The specific scenario is: An application that provides optional password-protection needs to display a Login page and restrict users from navigating into the app until they have successfully logged in. The optimal User experience and expectations would be:

  1.  If password protection is not enabled, app should function normally in terms of navigation.
  2.  If password is enabled, the first screen the user should see no matter how they enter the app (startup or returning via Back button) should be the login screen (this can be a popup or a page, doesn't impact this discussion).
  3.  If the user logs in successfully, the app should resume where they left off.
  4.  If the user hits the Back button from the Login page, it should EXIT the app. To elaborate on point 3, just because there is a gatekeeper, it doesn't mean tombstoning should be abandoned.  The user will want to be placed as close to where they left off as possible, once they are allowed access into the app. As for point 4, since he does not really view himself as "inside" the app yet while on the Login page, the only expectation for the Back button at that point is to exit the app. With the current SDK, the requirements above cannot be met. Possible solutions:
  5.  Throw exception and exit app on Back button of Login page (BAD as Peter stated)
  6.  Disable Back button of Login page, only allow user to leave app via Start button (FAILS certification... I tried)
  7.  The Back button of the Login page takes you to a "blank" version of the app's Main page.  From here, he is only allowed to press Back to exit normally, or access the Login page again. Option #2 is not great, but I feel is an OK compromise, valuing preservation of the user's state in the app over allowing the use of the Back button to exit.  The certification team felt a bit differently though. Option #3 is problematic as well, since it destroys the user's backstack if he decided to press the Back button in the Login page.  The user is also unaware that this has happened.  However, from a certification perspective, this is probably the only approach that can be used at this point.
  • Anonymous
    April 22, 2011
    Hi Peter, I have similar scenario in my application. First page of application is login screen and after successfully loggedIn, app moves to main dashboard screen; If user press back button from bashboard screen I don't want to display login screen again as we have logout option in dashboard. I am throwing an exception if user presses back button from dashboard screen to exit from application; Is this okay for certification requirement?

  • Anonymous
    April 22, 2011
    Deepak, I would suggest that you use a Popup for this rather than a page. Technically you are violating the certification requirements by raising such an exception. Also if you can wait for the Mango tools, one of the features I demoed at Mix is the ability to remove such pages from the backstack, so things will improve in the future.