1 page.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, 23 but still sends users in a fiery rage when they try to use the application. 24 These are the applications that aren't <em>responsive</em> enough — the 25 ones that feel sluggish, hang or freeze for significant periods, or take too 26 long to process input. </p> 27 28 <p>In Android, the system guards against applications that are insufficiently 29 responsive for a period of time by displaying a dialog to the user, called the 30 Application Not Responding (ANR) dialog, shown at right in Figure 1. The user 31 can choose to let the application continue, but the user won't appreciate having 32 to act on this dialog every time he or she uses your application. It's critical 33 to design responsiveness into your application, so that the system never has 34 cause to display an ANR dialog to the user. </p> 35 36 <p>Generally, the system displays an ANR if an application cannot respond to 37 user 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 39 process incoming user input events. After a time, the system concludes that the 40 application is frozen, and displays the ANR to give the user the option to kill 41 it. </p> 42 43 <p>Similarly, if your application spends too much time building an elaborate in-memory 44 structure, or perhaps computing the next move in a game, the system will 45 conclude that your application has hung. It's always important to make 46 sure these computations are efficient using the techniques above, but even the 47 most 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 50 most of your work there. This keeps the main thread (which drives the user 51 interface event loop) running and prevents the system from concluding that your code 52 has frozen. Since such threading usually is accomplished at the class 53 level, you can think of responsiveness as a <em>class</em> problem. (Compare 54 this with basic performance, which was described above as a <em>method</em>-level 55 concern.)</p> 56 57 <p>This document describes how the Android system determines whether an 58 application is not responding and provides guidelines for ensuring that your 59 application 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 64 and Window Manager system services. Android will display the ANR dialog 65 for a particular application when it detects one of the following 66 conditions:</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 77 Android 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. 80 This means that anything your application is doing in the main thread that 81 takes a long time to complete can trigger the ANR dialog because your 82 application is not giving itself a chance to handle the input event or Intent 83 broadcast.</p> 84 85 <p>Therefore any method that runs in the main thread should do as little work 86 as possible. In particular, Activities should do as little as possible to set 87 up in key life-cycle methods such as <code>onCreate()</code> and 88 <code>onResume()</code>. Potentially long running operations such as network 89 or database operations, or computationally expensive calculations such as 90 resizing bitmaps should be done in a child thread (or in the case of databases 91 operations, via an asynchronous request). However, this does not mean that 92 your main thread should block while waiting for the child thread to 93 complete — nor should you call <code>Thread.wait()</code> or 94 <code>Thread.sleep()</code>. Instead of blocking while waiting for a child 95 thread to complete, your main thread should provide a {@link 96 android.os.Handler Handler} for child threads to post back to upon completion. 97 Designing your application in this way will allow your main thread to remain 98 responsive to input and thus avoid ANR dialogs caused by the 5 second input 99 event timeout. These same practices should be followed for any other threads 100 that 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 103 long running operations such as network or database operations that 104 you might accidentally be doing your main thread.</p> 105 106 <p>The specific constraint on IntentReceiver execution time emphasizes what 107 they were meant to do: small, discrete amounts of work in the background such 108 as saving a setting or registering a Notification. So as with other methods 109 called in the main thread, applications should avoid potentially long-running 110 operations or calculations in BroadcastReceivers. But instead of doing intensive 111 tasks via child threads (as the life of a BroadcastReceiver is short), your 112 application should start a {@link android.app.Service Service} if a 113 potentially long running action needs to be taken in response to an Intent 114 broadcast. As a side note, you should also avoid starting an Activity from an 115 Intent Receiver, as it will spawn a new screen that will steal focus from 116 whatever application the user is currently has running. If your application 117 has something to show the user in response to an Intent broadcast, it should 118 do so using the {@link android.app.NotificationManager Notification 119 Manager}.</p> 120 121 <h2 id="reinforcing">Reinforcing Responsiveness</h2> 122 123 <p>Generally, 100 to 200ms is the threshold beyond which users will perceive 124 lag (or lack of "snappiness," if you will) in an application. As such, here 125 are some additional tips beyond what you should do to avoid ANR that will help 126 make 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