summaryrefslogtreecommitdiffstats
path: root/docs/html/guide/practices/responsiveness.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/guide/practices/responsiveness.jd')
-rw-r--r--docs/html/guide/practices/responsiveness.jd140
1 files changed, 140 insertions, 0 deletions
diff --git a/docs/html/guide/practices/responsiveness.jd b/docs/html/guide/practices/responsiveness.jd
new file mode 100644
index 0000000..a00e3aa
--- /dev/null
+++ b/docs/html/guide/practices/responsiveness.jd
@@ -0,0 +1,140 @@
+page.title=Designing for Responsiveness
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#anr">What Triggers ANR?</a></li>
+ <li><a href="#avoiding">How to Avoid ANR</a></li>
+ <li><a href="#reinforcing">Reinforcing Responsiveness</a></li>
+</ol>
+
+</div>
+</div>
+
+<div class="figure">
+<img src="{@docRoot}images/anr.png" alt="Screenshot of ANR dialog box" width="240" height="320"/>
+<p><strong>Figure 1.</strong> An ANR dialog displayed to the user.</p>
+</div>
+
+<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 &mdash; the
+ones that feel sluggish, hang or freeze for significant periods, or take too
+long to process input. </p>
+
+<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, shown at right in Figure 1. 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. It's critical
+to design responsiveness into your application, so that the system never has
+cause to display an ANR dialog to the user. </p>
+
+<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 is frozen, and displays the ANR to give the user the option to kill
+it. </p>
+
+<p>Similarly, if your application spends too much time building an elaborate in-memory
+structure, or perhaps computing the next move in a game, the system will
+conclude that your application has hung. It's always important to make
+sure these computations are efficient using the techniques above, but even the
+most efficient code still takes time to run.</p>
+
+<p>In both of these cases, the recommended approach is to create a child thread and do
+most of your work there. This keeps the main thread (which drives the user
+interface event loop) running and prevents the system from concluding that your code
+has frozen. Since such threading usually is accomplished at the class
+level, you can think of responsiveness as a <em>class</em> problem. (Compare
+this with basic performance, which was described above as a <em>method</em>-level
+concern.)</p>
+
+<p>This document describes how the Android system determines whether an
+application is not responding and provides guidelines for ensuring that your
+application stays responsive. </p>
+
+<h2 id="anr">What Triggers ANR?</h2>
+
+<p>In Android, application responsiveness is monitored by the Activity Manager
+and Window Manager system services. Android will display the ANR dialog
+for a particular application when it detects one of the following
+conditions:</p>
+<ul>
+ <li>No response to an input event (e.g. key press, screen touch)
+ within 5 seconds</li>
+ <li>A {@link android.content.BroadcastReceiver BroadcastReceiver}
+ hasn't finished executing within 10 seconds</li>
+</ul>
+
+<h2 id="avoiding">How to Avoid ANR</h2>
+
+<p>Given the above definition for ANR, let's examine why this can occur in
+Android applications and how best to structure your application to avoid ANR.</p>
+
+<p>Android applications normally run entirely on a single (i.e. main) thread.
+This means that anything your application is doing in the main thread that
+takes a long time to complete can trigger the ANR dialog because your
+application is not giving itself a chance to handle the input event or Intent
+broadcast.</p>
+
+<p>Therefore any method that runs in the main thread should do as little work
+as possible. In particular, Activities should do as little as possible to set
+up in key life-cycle methods such as <code>onCreate()</code> and
+<code>onResume()</code>. Potentially long running operations such as network
+or database operations, or computationally expensive calculations such as
+resizing bitmaps should be done in a child thread (or in the case of databases
+operations, via an asynchronous request). However, this does not mean that
+your main thread should block while waiting for the child thread to
+complete &mdash; nor should you call <code>Thread.wait()</code> or
+<code>Thread.sleep()</code>. Instead of blocking while waiting for a child
+thread to complete, your main thread should provide a {@link
+android.os.Handler Handler} for child threads to post back to upon completion.
+Designing your application in this way will allow your main thread to remain
+responsive to input and thus avoid ANR dialogs caused by the 5 second input
+event timeout. These same practices should be followed for any other threads
+that display UI, as they are also subject to the same timeouts.</p>
+
+<p>You can use {@link android.os.StrictMode} to help find potentially
+long running operations such as network or database operations that
+you might accidentally be doing your main thread.</p>
+
+<p>The specific constraint on IntentReceiver execution time emphasizes what
+they were meant to do: small, discrete amounts of work in the background such
+as saving a setting or registering a Notification. So as with other methods
+called in the main thread, applications should avoid potentially long-running
+operations or calculations in BroadcastReceivers. But instead of doing intensive
+tasks via child threads (as the life of a BroadcastReceiver is short), your
+application should start a {@link android.app.Service Service} if a
+potentially long running action needs to be taken in response to an Intent
+broadcast. As a side note, you should also avoid starting an Activity from an
+Intent Receiver, as it will spawn a new screen that will steal focus from
+whatever application the user is currently has running. If your application
+has something to show the user in response to an Intent broadcast, it should
+do so using the {@link android.app.NotificationManager Notification
+Manager}.</p>
+
+<h2 id="reinforcing">Reinforcing Responsiveness</h2>
+
+<p>Generally, 100 to 200ms is the threshold beyond which users will perceive
+lag (or lack of "snappiness," if you will) in an application. As such, here
+are some additional tips beyond what you should do to avoid ANR that will help
+make your application seem responsive to users.</p>
+
+<ul>
+ <li>If your application is doing work in the background in response to
+ user input, show that progress is being made ({@link
+ android.widget.ProgressBar ProgressBar} and {@link
+ android.app.ProgressDialog ProgressDialog} are useful for this).</li>
+ <li>For games specifically, do calculations for moves in a child
+ thread.</li>
+ <li>If your application has a time-consuming initial setup phase, consider
+ showing a splash screen or rendering the main view as quickly as possible
+ and filling in the information asynchronously. In either case, you should
+ indicate somehow that progress is being made, lest the user perceive that
+ the application is frozen.</li>
+</ul>