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