1page.title=Designing for Responsiveness
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="#anr">What Triggers ANR?</a></li>
10  <li><a href="#avoiding">How to Avoid ANR</a></li>
11  <li><a href="#reinforcing">Reinforcing Responsiveness</a></li>
12</ol>
13
14</div>
15</div>
16
17<div class="figure">
18<img src="{@docRoot}images/anr.png" alt="Screenshot of ANR dialog box" width="240" height="320"/>
19<p><strong>Figure 1.</strong> An ANR dialog displayed to the user.</p>
20</div>
21
22<p>It's possible to write code that wins every performance test in the world,
23but still sends users in a fiery rage when they try to use the application.
24These are the applications that aren't <em>responsive</em> enough &mdash; the
25ones that feel sluggish, hang or freeze for significant periods, or take too
26long to process input. </p>
27
28<p>In Android, the system guards against applications that are insufficiently
29responsive for a period of time by displaying a dialog to the user, called the
30Application Not Responding (ANR) dialog, shown at right in Figure 1. The user
31can choose to let the application continue, but the user won't appreciate having
32to act on this dialog every time he or she uses your application. It's critical
33to design responsiveness into your application, so that the system never has
34cause to display an ANR dialog to the user. </p>
35
36<p>Generally, the system displays an ANR if an application cannot respond to
37user input. For example, if an  application blocks on some I/O operation
38(frequently a network access), then the main application thread won't be able to
39process incoming user input events. After a time, the system concludes that the
40application is frozen, and displays the ANR to give the user the option to kill
41it. </p>
42
43<p>Similarly, if your application spends too much time building an elaborate in-memory
44structure, or perhaps computing the next move in a game, the system will 
45conclude that your application has hung. It's always important to make
46sure these computations are efficient using the techniques above, but even the
47most efficient code still takes time to run.</p>
48
49<p>In both of these cases, the recommended approach is to create a child thread and do
50most of your work there. This keeps the main thread (which drives the user
51interface event loop) running and prevents the system from concluding that your code
52has frozen. Since such threading usually is accomplished at the class
53level, you can think of responsiveness as a <em>class</em> problem. (Compare
54this with basic performance, which was described above as a <em>method</em>-level
55concern.)</p>
56
57<p>This document describes how the Android system determines whether an
58application is not responding and provides guidelines for ensuring that your
59application stays responsive. </p>
60
61<h2 id="anr">What Triggers ANR?</h2>
62
63<p>In Android, application responsiveness is monitored by the Activity Manager
64and Window Manager system services. Android will display the ANR dialog
65for a particular application when it detects one of the following
66conditions:</p>
67<ul>  
68    <li>No response to an input event (e.g. key press, screen touch) 
69    within 5 seconds</li>
70    <li>A {@link android.content.BroadcastReceiver BroadcastReceiver} 
71    hasn't finished executing within 10 seconds</li>
72</ul>
73
74<h2 id="avoiding">How to Avoid ANR</h2>
75
76<p>Given the above definition for ANR, let's examine why this can occur in
77Android applications and how best to structure your application to avoid ANR.</p>
78
79<p>Android applications normally run entirely on a single (i.e. main) thread.
80This means that anything your application is doing in the main thread that
81takes a long time to complete can trigger the ANR dialog because your
82application is not giving itself a chance to handle the input event or Intent
83broadcast.</p>
84
85<p>Therefore any method that runs in the main thread should do as little work
86as possible. In particular, Activities should do as little as possible to set
87up in key life-cycle methods such as <code>onCreate()</code> and
88<code>onResume()</code>. Potentially long running operations such as network
89or database operations, or computationally expensive calculations such as
90resizing bitmaps should be done in a child thread (or in the case of databases
91operations, via an asynchronous request). However, this does not mean that
92your main thread should block while waiting for the child thread to
93complete &mdash; nor should you call <code>Thread.wait()</code> or
94<code>Thread.sleep()</code>. Instead of blocking while waiting for a child
95thread to complete, your main thread should provide a {@link
96android.os.Handler Handler} for child threads to post back to upon completion.
97Designing your application in this way will allow your main thread to remain
98responsive to input and thus avoid ANR dialogs caused by the 5 second input
99event timeout. These same practices should be followed for any other threads
100that display UI, as they are also subject to the same timeouts.</p>
101
102<p>You can use {@link android.os.StrictMode} to help find potentially
103long running operations such as network or database operations that
104you might accidentally be doing your main thread.</p>
105
106<p>The specific constraint on IntentReceiver execution time emphasizes what
107they were meant to do: small, discrete amounts of work in the background such
108as saving a setting or registering a Notification. So as with other methods
109called in the main thread, applications should avoid potentially long-running
110operations or calculations in BroadcastReceivers. But instead of doing intensive
111tasks via child threads (as the life of a BroadcastReceiver is short), your
112application should start a {@link android.app.Service Service} if a
113potentially long running action needs to be taken in response to an Intent
114broadcast. As a side note, you should also avoid starting an Activity from an
115Intent Receiver, as it will spawn a new screen that will steal focus from
116whatever application the user is currently has running. If your application
117has something to show the user in response to an Intent broadcast, it should
118do so using the {@link android.app.NotificationManager Notification
119Manager}.</p>
120
121<h2 id="reinforcing">Reinforcing Responsiveness</h2>
122
123<p>Generally, 100 to 200ms is the threshold beyond which users will perceive
124lag (or lack of "snappiness," if you will) in an application. As such, here
125are some additional tips beyond what you should do to avoid ANR that will help
126make your application seem responsive to users.</p>
127
128<ul>
129    <li>If your application is doing work in the background in response to
130    user input, show that progress is being made ({@link
131    android.widget.ProgressBar ProgressBar} and {@link
132    android.app.ProgressDialog ProgressDialog} are useful for this).</li>
133    <li>For games specifically, do calculations for moves in a child
134    thread.</li>
135    <li>If your application has a time-consuming initial setup phase, consider
136    showing a splash screen or rendering the main view as quickly as possible
137    and filling in the information asynchronously. In either case, you should
138    indicate somehow that progress is being made, lest the user perceive that
139    the application is frozen.</li>
140</ul>
141