Monday, May 17, 2010

When to Include an Exit Button in Android Apps (Hint: Never)

A couple of weeks ago I published my first Android App Surgery, a technical review of MySettings from JQSoft. One of my UX suggestions was that they drop the "Exit" menu item. This turned out to be more controversial than I expected and soon dominated the discussion in the comments.

So, when should your app include an exit button?

The Short Answer

Never.

The Long Answer

Your app doesn't need an exit button. It really doesn't. Arguments to the contrary can generally be summarized as:

  • Users expect it.
  • It's a way to let users say "stop doing everything and stop consuming juice".
Do Users Really Want It?

Let me posit this assertion: no they don't.

Of the apps that ship with the device (Gmail, Contacts, Maps, Gallery, etc.) exactly none of them include an exit button, and most users are comfortable with that. Nonetheless many developers are adamant, "I added it after users demanded it!".

Fair enough, so why do some users demand an exit button? How do they cope with the bundled apps without an exit button? In my experience what they really want is:
An unambiguous way to guarantee that an app will stop consuming resources (battery, CPU cycles, data transfer, etc).
The Goggles Do Nothing!

Many users perceive that an exit button implements this requirement and ask for it to be added. Developers, looking to please their users, obligingly add one. Shortly thereafter they both fail.
  • In most cases the exit button simply calls Activity.finish. This is exactly equivalent to hitting the back button. Exactly. Services keep running and polling keeps happening. Users may think they've killed the app but they haven't, and soon they'll be even more annoyed.
  • Exit behavior is now ambiguous. Should your exit button just close the Activity, or should it also stop all associated Services, Receivers, and Alarms? What should back do? What happens if they hit home instead? What happens if your app has a widget? Should the exit button stop that from updating too?
The solution is to make the back button behave as you'd expect the exit button to. Better yet, simply stop consuming resources whenever the app isn't visible.
Users: Consider this. If an app needs an exit button because the back button doesn't properly manage resource use, what do you think the chances are that this exit button will be implemented properly?

Kill Everything When Not in Use

As soon as an app isn't visible its onStop handler is fired, as soon as it's not the foreground Activity onPause is triggered. This happens no matter what the circumstance - including hitting the back or home buttons or selecting a notification.

At this point (ideally within onPause) you should behave as though your user has hit exit. Location and Sensor Listeners should be removed, Services stopped and unbound, and Intent Receivers unregistered.

Once your app moves back to the foreground - triggering onStart and onResume - you hook everything back up.

"Sure," you're thinking, "but what about apps that need to run in the background?"

Foreground Services and Ongoing Notifications

Some applications, such as turn-by-turn navigation and music players, need to run (and use resources like GPS) while invisible. This is generally achieved using a foreground Service. It's also the only reason for creating a foreground Service.

Users should always know if such a Service is running, and be provided with a simple way of unambiguously turning it off when it is. In navigation there's an "exit navigation" menu item. Pausing playback in a music player is enough to kill the playback Service. In both cases ongoing notifications provide a simple shortcut to the app, where you can easily stop the Service.

As far as the user is concerned, if the app isn't visible and there's no notification icon it's not consuming resources. If there's an icon, it's running in the background and I can click the notification to go turn it off.

Background Services and Polling

Some applications (such as News & Weather) need to occasionally run in the background to get updates. Whenever possible use inexact repeating Alarms to schedule your updates, and then kill your service as soon as the update is complete.

This will help with resource use, but is still only half the answer. How can a user demand the app stop using resources completely?

What's the easiest way for me to prevent every app from transferring data?

Settings > Accounts & sync > Background data

Unchecking this should ensure that no app send or receive data while it's not visible. However: This needs to be enforced at an application level - so if this comes as a surprise to you have a fix to implement and an update to go push.

Go ahead, I'll wait.

Offer Users Options


Provided the user is cool with background updates in general, you need to let them adjust the frequency - or disable them - for your app. Be conservative by default. If users aren't getting updates as quickly as they want they'll look for a way to increase the frequency.

Be Adaptive

A Twitter discussion from this post resulted in a suggestion that "Android should offer a way to listen for low battery so that an app can be more conservative with it's use of resources." Register a Broadcast Receiver and thou shalt receive.

You can also monitor for things like connectivity status and type, so you can disable updates when there's no data connection, or modify the frequency based on the connection type.

In each case it's always good practice to offer these tweaks as user configurable options.

Conclusion

If you build an application that's predictable, configurable, and unambiguous your users won't ask for an exit button. The first time they see an unknown background Service that's been running for an hour, or the GPS icon unexpectedly starts flashing, or the device gets hot while in their pocket they're going to get narky.

Next on my hit list: Splash screens, task killers, and modal "loading" dialogs.

34 comments:

Berdon said...

What about applications that access an account of some sort with private/secure data?

Exiting might include finalizing a session - I suppose this would then be considering "Logging Out" rather than exiting...

Mark said...

Great post!

I'd never heard of getBackgroundDataSetting() before. I'd imagine the vast majority of other devs haven't either. Does it affect anything else, such as NetworkInfo??

It would be good if non-visible apps would receive a NetworkInfo that at least appears to be offline.

Mario Peshev said...

How about service-based applications that you don't expect running but you have forgot to close? I have few messengers that run in background and I always get annoyed when I notice GPRS traffic leak because of my non-closure. There are also buggy applications from the market that keep draining battery life when not closed. I'm not quite sure if the task killer is enough for that, I just don't like the 'non-exit' concept.

schwiz said...

Google's official navigation app has an exit button :-0

maeglin73 said...

"Google's official navigation app has an exit button :-0"
...which was already addressed in the article. Did you read it?

Mario:
Buggy applications aside, if an app has a background service that is designed to run until explicitly stopped by the user, then it'll have a way to stop it. IM applications have a "log out" button, or something similar, which should do the job of disconnecting and stopping their background services.

Commons Guy said...

@Berdon:

Exactly. I find it simplest to think of designing Android app flows as if you were designing a Web app. At most, a Web app *might* have a "logout" option, if it is particularly secure, but most sites (and users) tend to rely on an automatic timeout. And many Web apps skip the "logout" process as well.

@Mario Peshev:

What makes you think that developers who write buggy apps will somehow magically be able to write non-buggy "exit" options?

jrishel said...

I totally get where this article is coming from, and mostly agree... BUT, I still like that most twitter applications have an exit option especially when I'm evaluating multiple twitter clients. For example, I have Twidroid, Touiteur, and Twitter for Android installed, and depending which one I want to alert me for my updates, it's much easier to tell Twidroid and Touiteur to exit than it is to tell the Official Twitter app to stop polling for updates. Best I could do was set it to once a day, or turn off notifications, which was a lot more detailed than I wanted it to be.

True, in every day use, I'd never use an exit button in these apps, but it's a very convenient way of telling an app that normally does background polling to stop doing it until I manually launch it again.

Daniel Velazco said...

@Berdon: everytime you "exit" the application by hitting home or back, the application will call onPause(), you can Override this and log the user out or lock the session when this is called.

Checkout "mint.com" from the Android market, and enable the pin lock feature on the settings, I think it's one of the easiest-to-see examples.

Mario Peshev said...

@Commons Guy, I just prefer to know that 'exit' exists and to keep track of the KBs from my GPRS package. The non-existence of EXIT makes me unsure of the battery/traffic drain.

@jrishel - Twidroid is the app in question here. When I omit the "Exit", I usually notice updates and activity later.

Daniel Velazco said...

@jrishel: When you hit "exit" on those twitter apps, they are just calling Activity.finish() and the pollings will continue since they are probably using the AlarmManager to poll tweets. When an activity calls finish(), the AlarmManager scheduled services don't stop, unless the developer makes it work that way.

wjmay said...

I disagree. I am a fan of the exit button. Its a way for me to know that the application is done doing whatever its doing, and no background work will happen.

For example, if I had something that tracks my position, but I only wanted it to track me for a short period of time, i want to simply hit "exit" when I am done. It give me peace of mind.

Or what if I want to go to bed, but I want to stop twitter from updating while I am asleep. I don't want to mute my phone... its there for emergencies. I simply want to exit my twitter client.

Users do not want to mess with settings to stop background services from working.

Daniel Velazco said...

@wjmay: when you click the exit button you are not really exiting the app. The activity "finishes" and its the same thing as hitting the back button, it will do the same thing.

Also, if you want to sleep quitely while still letting your phone ring at night you should checkout Bedside, and if you don't like using your phone as a night clock checkout the included widget.

MatthewPatience said...

Excellent read. Thank you. I completely agree.

Christopher said...

> "Android should offer a way to listen for low battery"
> "Register a (BATTERY_CHANGED) Broadcast Receiver and thou shalt receive."

Is it really worth waking up/starting X number of processes for every single battery change event?

Is there a likelihood of a separate "low battery" broadcast action in future?

John said...

Certain apps that run obtrusively or noisily should have a button that assures the user that this activity is going to stop. For instance, after using Google maps navigation to get to my destination, hitting the Exit Navigation button assures me that the app isn't going to scream out that my GPS signal is lost in the middle of a business meeting.

Daniel Velazco said...

@John:
As addressed in the article, the Exit button in Google Maps Navigation is to stop the foregroundService. Regular apps do not use foreground services and they stop by themselves.

Chnoch said...

One App where I would like to see an exit button is the browser. After surfing a while i really don't want to click back a couple of times (and partially reloading the pages, depending on what browser it is) until i know the browser is done. If i just press home i assume it's still taking up memory space to be able to relaunch quickly and it's not properly closed.
This counts for other apps that have a long "back key history". The browser was just the first to come to mind.

Otherwise I agree that there doesn't need to be an exit button

Jay said...

What if your app consists of several screens, and the user is 4-5 screens deep? Having a one click solution (or perhaps two clicks if it's menu -> exit) could provide a better user experience than having them hammer the back button several times.

For the most part, I agree with the article, but there's almost always an exception.

Al said...

My app allows users to connect and chat on multiple irc servers and uses a foreground service.

I have an exit option in the menu, which, when triggered, disconnects from all servers, stops the service, unregisters all receivers and finishes. This is the easiest way for users to completely stop all activity in my app although manually disconnecting all servers and leaving the app will have the same effect.

For my app, I see the exit button as being essential but I'd be interested in hearing how I could replace it.

Anonymous said...

Al,

Just change the "exit" button to "logout" and make sure you have an icon in the notification area and you are in spirit doing what this article advocates. You are doing a foreground service which is discussed.

Jess R. said...

As far as the browser is concerned, when I'm done I close all the windows I was browsing by bringing up the menu and then Windows. This gets you all the way back to the Google page and you can then press back ONCE and close the browser. Because yes, if you just hit HOME it will continue to keep all the windows you were viewing open and running.

For everything else I use the App Killer...putting the widget for it on your desktop really helps with this. I press it a few times a day. My battery stays charged for a long time and charges really fast, even when plugged into my computer through USB. My husband's is constantly running out because he NEVER uses the app killer.

Use the app killer if you're really worried about it. You can even set it not to kill certain things.

The only thing you really need a quit button for is Pandora. I'm a little annoyed that the music player that comes with the Droid doesn't have one.

Pilot_51 said...

I agree with Chnoch. The first thing I thought when I read that there should never be an exit button was that the official browser NEEDS it. Hitting the back button some 10 or so times after a little browsing simply to exit is a bit annoying. If I don't do that and "exit" it some other way like switching to another app with the home button, I later find the browser in the running processes, which debatably seems to slow down the phone one way or another.

This is one significant reason why I use Dolphin Browser, because the menu has an exit while the back button still goes back to the previous page as expected. The process of properly exiting is then trimmed down from several seconds to about 1 second.

For apps that don't have multiple pages to go back through just to exit, then yes, there isn't much point to it. But on the other hand, is it really a big deal if an exit option is included anyway? What I gathered from the article was that it simply isn't needed, instead of being bad design, but worded to make it sound like bad design. Is there a problem having two ways to do the same thing? It is similar to having multiple ways to exit a PC application, which are generally File > Exit, clicking the X, or right-clicking it in the Task Bar and clicking Exit. It also gives more flexibility to the user, allowing them to pick the method that is most convenient or if broken hardware prevents one of the methods. Just because the back-end doesn't need it doesn't mean it's not useful on the front-end for the users.

I released my first app a couple days ago which includes an exit button. This article brought that subconscious design decision into question and I'll put some consideration into removing it, but I don't think it's big enough of a deal to change it when no users complain about the exit button being there.

My two cents.

Daniel Velazco said...

@Jay: have you ever used the "Home Button" to exit an application? Yes, thats the way to exit out of the app quickly without having to go back too much

Hobohemian said...

very good - thanks - especially the getBackgroundDataSetting() stuff

jrishel said...

@Daniel Velazco, I'm pretty sure the app developers of twidroid and touiteur are doing more than just calling finish()
Perhaps exit is the wrong term? Should they call it "stop notifications and polling until next launch" hard to fit that on button label though :-)

Daniel Velazco said...

@jrishel:

Sure, and let's say they are, with that we could say these are the cases of an "Exit" button:

1) Regular Apps: No need of an exit button.
2) Foreground Services: They could use a "Stop Service" button (just like Google Navigation does).
3) Regular Apps with Background Services: I guess "Disable" is the right term to use in the case of Touiteur/Twidroid, and maybe, for the sake of user-friendliness, it might as well just stay as "Exit".

But, we all go back to the same. From the developer's perspective, there's still no need for an "exit" method the way everybody is used to.

Alan Gerow said...

Many apps use the back button for in-app navigation. To successfully navigate out of an app, it requires back-tracking through the entire app. Simply hitting the home button is equally inconsistent because of how apps handled the very difference you mentioned between the two methods of exiting an app.

Mainly, closing and exiting an app are different. For many apps, including web browsers and Google Maps, hitting the home button should pause the experience. Reopening the app should continue the state of the program as it as so if the user were interrupted they can restart.

With exiting, the experience should end so that when the app is started, it is fresh. This is a different experience from before. This is inconsistently accomplished with the back button with some apps one hit of the back button, two hits, complete back-track, or a separate exit option. Essentially, an exit menu option is clear, concise, if implemented consistently would be unambiguous and would allow the user to finish their task differently than if they were interrupted in their task. For a browser, this would clear cache and tabs, for maps it would start the map back at center or home instead of on a previous search, start from a fresh playlist in a music player, etc.

I personally believe all apps should implement an exit menu item. Hitting home should save the state of the app for resuming. The back button is not intuitive or able to be consistently implemented due to in-app usage of the button (back buttons in browsers, previous tracks in music players, undo in editing programs). An OS provided exit button or consistent implementation of an exit button in the menu is my preference as a user.

Anonymous said...

Great. Almost same suggestion from this site: http://www.meatspin.com

Mario Peshev said...

@Alan, I prefer the 'back' trick when we don't have "Exit", but 'backing' in a browser could take 20+ clicks if you have browsed a lot. Content is also refreshed which is bandwidth related etc.

Mort said...

I think the main problem is that users just don't get Android's task and memory management.

Often, the only "respected" way to implement "exit" for them is to kill the process, so that nothing will show up in task managers or "running services". Way too many users think any process in memory does use CPU time and blocks free memory, as it does in Windows.
And then the users will complain nontheless that wanted background jobs (like getting new Tweets) aren't working...

Even if you just add some broadcast Intents to your manifest (like SD (un)mount, or audio becoming noisy), people will complain why your app is "running all the time" (was once loaded by Android to deliver the broadcast).

I guess the only reasonable way to fix the problem with "when should services work" (like getting new Tweets) is to offer a schedule plan.
However, some users will always expect exactly what the app isn't doing, like (not) getting new Tweets when the app was left with Home, and they also won't like lots of options (or not even take a look at them)...

Sometimes I wish there was no way for users to see anything system internal but the services actually doing something (i.e. executing code, not only lingering about waiting for new Intents/startServices).

Anonymous said...

How about a long-click on the back button which would mean 'take me aaall the way back', exiting the application, and resetting the state to default for the next time the app is run?

David C Bauman said...

My biggest problem with the "Don't include an exit" button is functional, not perceptual. I know the Lifecycle of Android applications, and I know that "exit" really isn't. But suppose the following: I'm in an application, lets say, Gmail. I click on a link, it takes me to my browser. I read the link, see something interesting that's continued on page 2 of the article. By the time I'm done reading all 4 pages of this article, I want to go back to my email. So naturally, I hit "Back". Which reloads page 5. And then 4... 3... 2... 1... and once more, oh, there we go, there's my email so I can reply to the person saying "Good read, thanks!". But I suppose I could have just pressed "Home" and loaded gmail again. Or, long pressed "Home" and used the "Recent Applications" window to select gmail again. But none of that seems to me, as the end user, nearly as intuitive as an "Exit" button under the menu. And, oh yea, then the next time I open my browser from my desktop, I'm back where I left it, in the middle of that article, which I wouldn't be if I hit "Back" (assuming it was a one page article). It would instead load my home page under that circumstance... With out an exit button, things are inconsistent. I don't care how that inconsistency is fixed, be it changing behaviors of existing buttons such as back (long press back to do a "super back" which would back you all the way out to the state before the app was "launched"?) or the inclusion of an exit button, it really doesn't bother me. When I load "Astro" the file manager, it is set up to start browsing my SDCard. So I go 4 directories deep, find what I'm looking for, and do my thing. If I hit home, I go there, if I switch to another app via long-press on the home button, I go there, and things are fine. Two days later, I hit Astro again, and, because it's still running and never terminated (sure, it isn't using resources, but it remembers its previous state since it didn't exit), I'm back in the same directory I was when I left it. This is assuming I didn't reboot my phone. If I did, it would behave like I expect, taking me to my default home path. I think the biggest issue with back and exit being the "same function" is that they're not consistent across the Android experience.

Eric said...

Nobody ever asked me to include an exit button ever for my app. And it has over 80.000 downloads and has different screens/activities. This, I think, is because the app behaves naturally for a user.

I am a strong supporter of the 'never include an exit button in your app' idea. The ONLY reason why a user (should) want this is to explicitly stop a service. For foreground services, this is natural. For background services, this means LOGOUT. Not, never ever it means EXIT, because it will not exit the app. (There really actually is no notion of exiting an app on Android.)

So please, developers, be free to implement a logout or stop service method, but no exit.

Dandandin said...

Look at fring, no exit button.
how to logout and stop him to being connected to msn/skype/irc/whatever and draining my precious battery?

you have two choices:
1. reboot
2. use a task manager

sometimes an exit button is a must
sometimes, poorly coded programs let me think that the forced monotasking imposed by apple is a good thing...

Post a Comment