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