1page.title=Designing for Seamlessness 2@jd:body 3 4<div id="qv-wrapper"> 5<div id="qv"> 6 7<h2>In this document</h2> 8<ol> 9 <li><a href="#drop">Don't Drop Data</a></li> 10 <li><a href="#expose">Don't Expose Raw Data</a></li> 11 <li><a href="#interrupt">Don't Interrupt the User</a></li> 12 <li><a href="#threads">Got a Lot to Do? Do it in a Thread</a></li> 13 <li><a href="#multiple-activities">Don't Overload a Single Activity Screen</a></li> 14 <li><a href="#themes">Extend System Themes</a></li> 15 <li><a href="#flexui">Design Your UI to Work with Multiple Screen Resolutions</a></li> 16 <li><a href="#network">Assume the Network is Slow</a></li> 17 <li><a href="#keyboard">Don't Assume Touchscreen or Keyboard</a></li> 18 <li><a href="#battery">Do Conserve the Device Battery</a></li> 19</ol> 20 21</div> 22</div> 23 24<p>Even if your application is fast and responsive, certain design decisions can 25still cause problems for users — because of unplanned interactions with 26other applications or dialogs, inadvertent loss of data, unintended blocking, 27and so on. To avoid these problems, it helps to understand the context in which 28your applications run and the system interactions that can affect your 29application. In short, you should strive to develop an application that 30interacts seamlessly with the system and with other applications. </p> 31 32<p>A common seamlessness problem is when an application's background process 33— for example, a service or broadcast receiver — pops up a dialog in 34response to some event. This may seem like harmless behavior, especially when 35you are building and testing your application in isolation, on the emulator. 36However, when your application is run on an actual device, your application may 37not have user focus at the time your background process displays the dialog. So 38it could end up that your application would display it's dialog behind the 39active application, or it could take focus from the current application and 40display the dialog in front of whatever the user was doing (such as dialing a 41phone call, for example). That behavior would not work for your application or 42for the user. </p> 43 44<p>To avoid these problems, your application should use the proper system 45facility for notifying the user — the 46{@link android.app.Notification Notification} classes. Using 47notifications, your application can signal the user that an event has 48taken place, by displaying an icon in the status bar rather than taking 49focus and interrupting the user.</p> 50 51<p>Another example of a seamlessness problem is when an activity inadvertently 52loses state or user data because it doesn't correctly implement the onPause() 53and other lifecycle methods. Or, if your application exposes data intended to be 54used by other applications, you should expose it via a ContentProvider, rather 55than (for example) doing so through a world-readable raw file or database.</p> 56 57<p>What those examples have in common is that they involve cooperating nicely 58with the system and other applications. The Android system is designed to treat 59applications as a sort of federation of loosely-coupled components, rather than 60chunks of black-box code. This allows you as the developer to view the entire 61system as just an even-larger federation of these components. This benefits you 62by allowing you to integrate cleanly and seamlessly with other applications, and 63so you should design your own code to return the favor.</p> 64 65<p>This document discusses common seamlessness problems and how to avoid them.</p> 66 67<h2 id="drop">Don't Drop Data</h2> 68 69<p>Always keep in mind that Android is a mobile platform. It may seem obvious to 70say it, but it's important to remember that another Activity (such as the 71"Incoming Phone Call" app) can pop up over your own Activity at any moment. 72This will fire the onSaveInstanceState() and onPause() methods, and will likely result in 73your application being killed.</p> 74 75<p>If the user was editing data in your application when the other Activity 76appeared, your application will likely lose that data when your application is 77killed. Unless, of course, you save the work in progress first. The "Android 78Way" is to do just that: Android applications that accept or edit input should 79override the onSaveInstanceState() method and save their state in some appropriate 80fashion. When the user revisits the application, she should be able to 81retrieve her data.</p> 82 83<p>A classic example of a good use of this behavior is a mail application. If the 84user was composing an email when another Activity started up, the application 85should save the in-process email as a draft.</p> 86 87<h2 id="expose">Don't Expose Raw Data</h2> 88 89<p>If you wouldn't walk down the street in your underwear, neither should your 90data. While it's possible to expose certain kinds of application to the world 91to read, this is usually not the best idea. Exposing raw data requires other 92applications to understand your data format; if you change that format, you'll 93break any other applications that aren't similarly updated.</p> 94 95<p>The "Android Way" is to create a ContentProvider to expose your data to other 96applications via a clean, well-thought-out, and maintainable API. Using a 97ContentProvider is much like inserting a Java language interface to split up and 98componentize two tightly-coupled pieces of code. This means you'll be able to 99modify the internal format of your data without changing the interface exposed 100by the ContentProvider, and this without affecting other applications.</p> 101 102<h2 id="interrupt">Don't Interrupt the User</h2> 103 104<p>If the user is running an application (such as the Phone application during a 105call) it's a pretty safe bet he did it on purpose. That's why you should avoid 106spawning activities except in direct response to user input from the current 107Activity.</p> 108 109<p>That is, don't call startActivity() from BroadcastReceivers or Services running in 110the background. Doing so will interrupt whatever application is currently 111running, and result in an annoyed user. Perhaps even worse, your Activity may 112become a "keystroke bandit" and receive some of the input the user was in the 113middle of providing to the previous Activity. Depending on what your 114application does, this could be bad news.</p> 115 116<p>Instead of spawning Activity UIs directly from the background, you should 117instead use the NotificationManager to set Notifications. These will appear in 118the status bar, and the user can then click on them at his leisure, to see 119what your application has to show him.</p> 120 121<p>(Note that all this doesn't apply to cases where your own Activity is already 122in the foreground: in that case, the user expects to see your next Activity in 123response to input.)</p> 124 125<h2 id="threads">Got a Lot to Do? Do it in a Thread</h2> 126 127<p>If your application needs to perform some expensive or long-running 128computation, you should probably move it to a thread. This will prevent the 129dreaded "Application Not Responding" dialog from being displayed to the user, 130with the ultimate result being the fiery demise of your application.</p> 131 132<p>By default, all code in an Activity as well as all its Views run in the same 133thread. This is the same thread that also handles UI events. For example, when 134the user presses a key, a key-down event is added to the Activity's main 135thread's queue. The event handler system needs to dequeue and handle that 136event quickly; if it doesn't, the system concludes after a few seconds that 137the application is hung and offers to kill it for the user.</p> 138 139<p>If you have long-running code, running it inline in your Activity will run it 140on the event handler thread, effectively blocking the event handler. This will 141delay input processing, and result in the ANR dialogs. To avoid this, move 142your computations to a thread. This <a 143href="responsiveness.html">Design for Responsiveness</a> document 144discusses how to do that..</p> 145 146<h2 id="multiple-activities">Don't Overload a Single Activity Screen</h2> 147 148<p>Any application worth using will probably have several different screens. 149When designing the screens of your UI, be sure to make use of multiple Activity 150object instances.</p> 151 152<p>Depending on your development background, you may interpret an Activity as 153similar to something like a Java Applet, in that it is the entry point for 154your application. However, that's not quite accurate: where an Applet subclass 155is the single entry point for a Java Applet, an Activity should be thought of 156as one of potentially several entry points to your application. The only 157difference between your "main" Activity and any others you might have is that 158the "main" one just happens to be the only one that expressed an interest in 159the "android.intent.action.MAIN" action in your AndroidManifest..xml file.</p> 160 161<p>So, when designing your application, think of your application as a federation 162of Activity objects. This will make your code a lot more maintainable in the long 163run, and as a nice side effect also plays nicely with Android's application 164history and "backstack" model.</p> 165 166<h2 id="themes">Extend System Themes</h2> 167 168<p>When it comes to the look-and-feel of the user interface, it's important to 169blend in nicely. Users are jarred by applications which contrast with the user 170interface they've come to expect. When designing your UIs, you should try and 171avoid rolling your own as much as possible. Instead, use a Theme. You 172can override or extend those parts of the theme that you need to, but at least 173you're starting from the same UI base as all the other applications. For all 174the details, read <a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p> 175 176<h2 id="flexui">Design Your UI to Work with Multiple Screen Resolutions</h2> 177 178<p>Different Android-powered devices will support different screen resolutions. 179Some will even be able to change resolutions on the fly, such as by switching 180to landscape mode. It's important to make sure your layouts and drawables 181are flexible enough to display properly on a variety of device screens.</p> 182 183<p>Fortunately, this is very easy to do. In brief, what you must do is 184provide different versions of your artwork (if you use any) for the key 185resolutions, and then design your layout to accommodate various dimensions. 186(For example, avoid using hard-coded positions and instead use relative 187layouts.) If you do that much, the system handles the rest, and your 188application looks great on any device.</p> 189 190<h2 id="network">Assume the Network is Slow</h2> 191 192<p>Android devices will come with a variety of network-connectivity options. All 193will have some data-access provision, though some will be faster than others. 194The lowest common denominator, however, is GPRS, the non-3G data service for 195GSM networks. Even 3G-capable devices will spend lots of time on non-3G 196networks, so slow networks will remain a reality for quite a long time to 197come.</p> 198 199<p>That's why you should always code your applications to minimize network 200accesses and bandwidth. You can't assume the network is fast, so you should 201always plan for it to be slow. If your users happen to be on faster networks, 202then that's great — their experience will only improve. You want to avoid the 203inverse case though: applications that are usable some of the time, but 204frustratingly slow the rest based on where the user is at any given moment are 205likely to be unpopular.</p> 206 207<p>One potential gotcha here is that it's very easy to fall into this trap if 208you're using the emulator, since the emulator uses your desktop computer's 209network connection. That's almost guaranteed to be much faster than a cell 210network, so you'll want to change the settings on the emulator that simulate 211slower network speeds. You can do this in Eclipse, in the "Emulator Settings" 212tab of your launch configuration or via a <a 213href="{@docRoot}guide/developing/tools/emulator.html#netspeed">command-line 214option</a> when starting the emulator.</p> 215 216<h2 id="keyboard">Don't Assume Touchscreen or Keyboard</h2> 217 218<p> 219Android will support a variety of handset form-factors. That's a fancy way of 220saying that some Android devices will have full "QWERTY" keyboards, while 221others will have 40-key, 12-key, or even other key configurations. Similarly, 222some devices will have touch-screens, but many won't. 223</p><p> 224When building your applications, keep that in mind. Don't make assumptions 225about specific keyboard layouts -- unless, of course, you're really interested 226in restricting your application so that it can only be used on those devices. 227</p> 228 229<h2 id="battery">Do Conserve the Device Battery</h2> 230<p> 231A mobile device isn't very mobile if it's constantly plugged into the 232wall. Mobile devices are battery-powered, and the longer we can make that 233battery last on a charge, the happier everyone is — especially the user. 234Two of the biggest consumers of battery power are the processor, and the 235radio; that's why it's important to write your applications to do as little 236work as possible, and use the network as infrequently as possible. 237</p><p> 238Minimizing the amount of processor time your application uses really comes 239down to <a href="performance.html">writing efficient 240code</a>. To minimize the power drain from using the radio, be sure to handle 241error conditions gracefully, and only fetch what you need. For example, don't 242constantly retry a network operation if one failed. If it failed once, it's 243likely because the user has no reception, so it's probably going to fail again 244if you try right away; all you'll do is waste battery power. 245</p><p> 246Users are pretty smart: if your program is power-hungry, you can count on 247them noticing. The only thing you can be sure of at that point is that your 248program won't stay installed very long. 249</p> 250