M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
page.title=Application Design Goals
@jd:body
<p>When learning how to build applications on a new platform, you first learn what APIs are available and how to use them. Later, you learn the nuances of the platform. Put another way: first you learn how you <em>can</em> build applications; later, you learn how you <em>should</em> build them, to ensure that your applications offer outstanding performance and a great user experience. </p>
<p>The documents below help you learn the nuances of Android and get started building great applications more quickly, They discuss important aspects of application design that directly influence the user experience of your application, when in the hands of a mobile device user. You should read and consider these design goals as you plan your application and throughout its development, especially if you are new to developing for mobile devices.</p>
<p>Successful mobile applications offer an outstanding user experience, in addition to a compelling technical feature set. The user experience is more than just its visual design or UI flow. It is also influenced by how well the application responds to the user's keypresses and other actions, how it well it interacts with other applications, and how fully and efficiently it uses device and system capabilities.</p>
<p>An outstanding user experience has three key characteristics: it is
<em>fast</em>; it is <em>responsive</em>; and it is <em>seamless</em>. Of course
every platform since the dawn of computing has probably cited those same three
qualities at one time or another. However, each platform achieves them in
different ways; the documents below explain how you can build Android
applications that are fast, responsive, and seamless. </p>
<ul>
<li><a href="performance.html">Designing for Performance</a> (writing efficient Android code)</a></li>
<li><a href="responsiveness.html">Designing for Responsiveness</a> (avoiding ANR)</a></li>
<li><a href="seamlessness.html">Designing for Seamlessness</a> (coexisting with other applications)</a></li>
</ul>

View File

@@ -0,0 +1,433 @@
page.title=Designing for Performance
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
<li><a href="#object_creation">Avoid Creating Objects</a></li>
<li><a href="#myths">Performance Myths</a></li>
<li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
<li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
<li><a href="#use_final">Use Static Final For Constants</a></li>
<li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
<li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
<li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
<li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
<li><a href="#library">Know And Use The Libraries</a></li>
<li><a href="#native_methods">Use Native Methods Judiciously</a></li>
<li><a href="#closing_notes">Closing Notes</a></li>
</ol>
</div>
</div>
<p>An Android application will run on a mobile device with limited computing
power and storage, and constrained battery life. Because of
this, it should be <em>efficient</em>. Battery life is one reason you might
want to optimize your app even if it already seems to run "fast enough".
Battery life is important to users, and Android's battery usage breakdown
means users will know if your app is responsible draining their battery.</p>
<p>Note that although this document primarily covers micro-optimizations,
these will almost never make or break your software. Choosing the right
algorithms and data structures should always be your priority, but is
outside the scope of this document.</p>
<a name="intro" id="intro"></a>
<h2>Introduction</h2>
<p>There are two basic rules for writing efficient code:</p>
<ul>
<li>Don't do work that you don't need to do.</li>
<li>Don't allocate memory if you can avoid it.</li>
</ul>
<h2 id="optimize_judiciously">Optimize Judiciously</h2>
<p>This document is about Android-specific micro-optimization, so it assumes
that you've already used profiling to work out exactly what code needs to be
optimized, and that you already have a way to measure the effect (good or bad)
of any changes you make. You only have so much engineering time to invest, so
it's important to know you're spending it wisely.
<p>(See <a href="#closing_notes">Closing Notes</a> for more on profiling and
writing effective benchmarks.)
<p>This document also assumes that you made the best decisions about data
structures and algorithms, and that you've also considered the future
performance consequences of your API decisions. Using the right data
structures and algorithms will make more difference than any of the advice
here, and considering the performance consequences of your API decisions will
make it easier to switch to better implementations later (this is more
important for library code than for application code).
<p>(If you need that kind of advice, see Josh Bloch's <em>Effective Java</em>,
item 47.)</p>
<p>One of the trickiest problems you'll face when micro-optimizing an Android
app is that your app is pretty much guaranteed to be running on multiple
hardware platforms. Different versions of the VM running on different
processors running at different speeds. It's not even generally the case
that you can simply say "device X is a factor F faster/slower than device Y",
and scale your results from one device to others. In particular, measurement
on the emulator tells you very little about performance on any device. There
are also huge differences between devices with and without a JIT: the "best"
code for a device with a JIT is not always the best code for a device
without.</p>
<p>If you want to know how your app performs on a given device, you need to
test on that device.</p>
<a name="object_creation"></a>
<h2>Avoid Creating Objects</h2>
<p>Object creation is never free. A generational GC with per-thread allocation
pools for temporary objects can make allocation cheaper, but allocating memory
is always more expensive than not allocating memory.</p>
<p>If you allocate objects in a user interface loop, you will force a periodic
garbage collection, creating little "hiccups" in the user experience.</p>
<p>Thus, you should avoid creating object instances you don't need to. Some
examples of things that can help:</p>
<ul>
<li>When extracting strings from a set of input data, try
to return a substring of the original data, instead of creating a copy.
You will create a new String object, but it will share the char[]
with the data.</li>
<li>If you have a method returning a string, and you know that its result
will always be appended to a StringBuffer anyway, change your signature
and implementation so that the function does the append directly,
instead of creating a short-lived temporary object.</li>
</ul>
<p>A somewhat more radical idea is to slice up multidimensional arrays into
parallel single one-dimension arrays:</p>
<ul>
<li>An array of ints is a much better than an array of Integers,
but this also generalizes to the fact that two parallel arrays of ints
are also a <strong>lot</strong> more efficient than an array of (int,int)
objects. The same goes for any combination of primitive types.</li>
<li>If you need to implement a container that stores tuples of (Foo,Bar)
objects, try to remember that two parallel Foo[] and Bar[] arrays are
generally much better than a single array of custom (Foo,Bar) objects.
(The exception to this, of course, is when you're designing an API for
other code to access; in those cases, it's usually better to trade
correct API design for a small hit in speed. But in your own internal
code, you should try and be as efficient as possible.)</li>
</ul>
<p>Generally speaking, avoid creating short-term temporary objects if you
can. Fewer objects created mean less-frequent garbage collection, which has
a direct impact on user experience.</p>
<a name="myths" id="myths"></a>
<h2>Performance Myths</h2>
<p>Previous versions of this document made various misleading claims. We
address some of them here.</p>
<p>On devices without a JIT, it is true that invoking methods via a
variable with an exact type rather than an interface is slightly more
efficient. (So, for example, it was cheaper to invoke methods on a
<code>HashMap map</code> than a <code>Map map</code>, even though in both
cases the map was a <code>HashMap</code>.) It was not the case that this
was 2x slower; the actual difference was more like 6% slower. Furthermore,
the JIT makes the two effectively indistinguishable.</p>
<p>On devices without a JIT, caching field accesses is about 20% faster than
repeatedly accesssing the field. With a JIT, field access costs about the same
as local access, so this isn't a worthwhile optimization unless you feel it
makes your code easier to read. (This is true of final, static, and static
final fields too.)
<a name="prefer_static" id="prefer_static"></a>
<h2>Prefer Static Over Virtual</h2>
<p>If you don't need to access an object's fields, make your method static.
Invocations will be about 15%-20% faster.
It's also good practice, because you can tell from the method
signature that calling the method can't alter the object's state.</p>
<a name="internal_get_set" id="internal_get_set"></a>
<h2>Avoid Internal Getters/Setters</h2>
<p>In native languages like C++ it's common practice to use getters (e.g.
<code>i = getCount()</code>) instead of accessing the field directly (<code>i
= mCount</code>). This is an excellent habit for C++, because the compiler can
usually inline the access, and if you need to restrict or debug field access
you can add the code at any time.</p>
<p>On Android, this is a bad idea. Virtual method calls are expensive,
much more so than instance field lookups. It's reasonable to follow
common object-oriented programming practices and have getters and setters
in the public interface, but within a class you should always access
fields directly.</p>
<p>Without a JIT, direct field access is about 3x faster than invoking a
trivial getter. With the JIT (where direct field access is as cheap as
accessing a local), direct field access is about 7x faster than invoking a
trivial getter. This is true in Froyo, but will improve in the future when
the JIT inlines getter methods.</p>
<a name="use_final" id="use_final"></a>
<h2>Use Static Final For Constants</h2>
<p>Consider the following declaration at the top of a class:</p>
<pre>static int intVal = 42;
static String strVal = "Hello, world!";</pre>
<p>The compiler generates a class initializer method, called
<code>&lt;clinit&gt;</code>, that is executed when the class is first used.
The method stores the value 42 into <code>intVal</code>, and extracts a
reference from the classfile string constant table for <code>strVal</code>.
When these values are referenced later on, they are accessed with field
lookups.</p>
<p>We can improve matters with the "final" keyword:</p>
<pre>static final int intVal = 42;
static final String strVal = "Hello, world!";</pre>
<p>The class no longer requires a <code>&lt;clinit&gt;</code> method,
because the constants go into static field initializers in the dex file.
Code that refers to <code>intVal</code> will use
the integer value 42 directly, and accesses to <code>strVal</code> will
use a relatively inexpensive "string constant" instruction instead of a
field lookup. (Note that this optimization only applies to primitive types and
<code>String</code> constants, not arbitrary reference types. Still, it's good
practice to declare constants <code>static final</code> whenever possible.)</p>
<a name="foreach" id="foreach"></a>
<h2>Use Enhanced For Loop Syntax</h2>
<p>The enhanced for loop (also sometimes known as "for-each" loop) can be used
for collections that implement the Iterable interface and for arrays.
With collections, an iterator is allocated to make interface calls
to hasNext() and next(). With an ArrayList, a hand-written counted loop is
about 3x faster (with or without JIT), but for other collections the enhanced
for loop syntax will be exactly equivalent to explicit iterator usage.</p>
<p>There are several alternatives for iterating through an array:</p>
<pre> static class Foo {
int mSplat;
}
Foo[] mArray = ...
public void zero() {
int sum = 0;
for (int i = 0; i &lt; mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i &lt; len; ++i) {
sum += localArray[i].mSplat;
}
}
public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
</pre>
<p><strong>zero()</strong> is slowest, because the JIT can't yet optimize away
the cost of getting the array length once for every iteration through the
loop.</p>
<p><strong>one()</strong> is faster. It pulls everything out into local
variables, avoiding the lookups. Only the array length offers a performance
benefit.</p>
<p><strong>two()</strong> is fastest for devices without a JIT, and
indistinguishable from <strong>one()</strong> for devices with a JIT.
It uses the enhanced for loop syntax introduced in version 1.5 of the Java
programming language.</p>
<p>To summarize: use the enhanced for loop by default, but consider a
hand-written counted loop for performance-critical ArrayList iteration.</p>
<p>(See also <em>Effective Java</em> item 46.)</p>
<a name="avoid_enums" id="avoid_enums"></a>
<h2>Avoid Enums Where You Only Need Ints</h2>
<p>Enums are very convenient, but unfortunately can be painful when size
and speed matter. For example, this:</p>
<pre>public enum Shrubbery { GROUND, CRAWLING, HANGING }</pre>
<p>adds 740 bytes to your .dex file compared to the equivalent class
with three public static final ints. On first use, the
class initializer invokes the &lt;init&gt; method on objects representing each
of the enumerated values. Each object gets its own static field, and the full
set is stored in an array (a static field called "$VALUES"). That's a lot of
code and data, just for three integers. Additionally, this:</p>
<pre>Shrubbery shrub = Shrubbery.GROUND;</pre>
<p>causes a static field lookup. If "GROUND" were a static final int,
the compiler would treat it as a known constant and inline it.</p>
<p>The flip side, of course, is that with enums you get nicer APIs and
some compile-time value checking. So, the usual trade-off applies: you should
by all means use enums for public APIs, but try to avoid them when performance
matters.</p>
<p>If you're using <code>Enum.ordinal</code>, that's usually a sign that you
should be using ints instead. As a rule of thumb, if an enum doesn't have a
constructor and doesn't define its own methods, and it's used in
performance-critical code, you should consider <code>static final int</code>
constants instead.</p>
<a name="package_inner" id="package_inner"></a>
<h2>Use Package Scope with Inner Classes</h2>
<p>Consider the following class definition:</p>
<pre>public class Foo {
private int mValue;
public void run() {
Inner in = new Inner();
mValue = 27;
in.stuff();
}
private void doStuff(int value) {
System.out.println("Value is " + value);
}
private class Inner {
void stuff() {
Foo.this.doStuff(Foo.this.mValue);
}
}
}</pre>
<p>The key things to note here are that we define an inner class (Foo$Inner)
that directly accesses a private method and a private instance field
in the outer class. This is legal, and the code prints "Value is 27" as
expected.</p>
<p>The problem is that the VM considers direct access to Foo's private members
from Foo$Inner to be illegal because Foo and Foo$Inner are different classes,
even though the Java language allows an inner class to access an outer class'
private members. To bridge the gap, the compiler generates a couple of
synthetic methods:</p>
<pre>/*package*/ static int Foo.access$100(Foo foo) {
return foo.mValue;
}
/*package*/ static void Foo.access$200(Foo foo, int value) {
foo.doStuff(value);
}</pre>
<p>The inner-class code calls these static methods whenever it needs to
access the "mValue" field or invoke the "doStuff" method in the outer
class. What this means is that the code above really boils down to a case
where you're accessing member fields through accessor methods instead of
directly. Earlier we talked about how accessors are slower than direct field
accesses, so this is an example of a certain language idiom resulting in an
"invisible" performance hit.</p>
<p>We can avoid this problem by declaring fields and methods accessed
by inner classes to have package scope, rather than private scope.
This runs faster and removes the overhead of the generated methods.
(Unfortunately it also means the fields could be accessed directly by other
classes in the same package, which runs counter to the standard
practice of making all fields private. Once again, if you're
designing a public API you might want to carefully consider using this
optimization.)</p>
<a name="avoidfloat" id="avoidfloat"></a>
<h2>Use Floating-Point Judiciously</h2>
<p>As a rule of thumb, floating-point is about 2x slower than integer on
Android devices. This is true on a FPU-less, JIT-less G1 and a Nexus One with
an FPU and the JIT. (Of course, absolute speed difference between those two
devices is about 10x for arithmetic operations.)</p>
<p>In speed terms, there's no difference between <code>float</code> and
<code>double</code> on the more modern hardware. Space-wise, <code>double</code>
is 2x larger. As with desktop machines, assuming space isn't an issue, you
should prefer <code>double</code> to <code>float</code>.</p>
<p>Also, even for integers, some chips have hardware multiply but lack
hardware divide. In such cases, integer division and modulus operations are
performed in software &mdash; something to think about if you're designing a
hash table or doing lots of math.</p>
<a name="library" id="library"></a>
<h2>Know And Use The Libraries</h2>
<p>In addition to all the usual reasons to prefer library code over rolling
your own, bear in mind that the system is at liberty to replace calls
to library methods with hand-coded assembler, which may be better than the
best code the JIT can produce for the equivalent Java. The typical example
here is <code>String.indexOf</code> and friends, which Dalvik replaces with
an inlined intrinsic. Similarly, the <code>System.arraycopy</code> method
is about 9x faster than a hand-coded loop on a Nexus One with the JIT.</p>
<p>(See also <em>Effective Java</em> item 47.)</p>
<a name="native_methods" id="native_methods"></a>
<h2>Use Native Methods Judiciously</h2>
<p>Native code isn't necessarily more efficient than Java. For one thing,
there's a cost associated with the Java-native transition, and the JIT can't
optimize across these boundaries. If you're allocating native resources (memory
on the native heap, file descriptors, or whatever), it can be significantly
more difficult to arrange timely collection of these resources. You also
need to compile your code for each architecture you wish to run on (rather
than rely on it having a JIT). You may even have to compile multiple versions
for what you consider the same architecture: native code compiled for the ARM
processor in the G1 can't take full advantage of the ARM in the Nexus One, and
code compiled for the ARM in the Nexus One won't run on the ARM in the G1.</p>
<p>Native code is primarily useful when you have an existing native codebase
that you want to port to Android, not for "speeding up" parts of a Java app.</p>
<p>(See also <em>Effective Java</em> item 54.)</p>
<a name="closing_notes" id="closing_notes"></a>
<h2>Closing Notes</h2>
<p>One last thing: always measure. Before you start optimizing, make sure you
have a problem. Make sure you can accurately measure your existing performance,
or you won't be able to measure the benefit of the alternatives you try.</p>
<p>Every claim made in this document is backed up by a benchmark. The source
to these benchmarks can be found in the <a href="http://code.google.com/p/dalvik/source/browse/#svn/trunk/benchmarks">code.google.com "dalvik" project</a>.</p>
<p>The benchmarks are built with the
<a href="http://code.google.com/p/caliper/">Caliper</a> microbenchmarking
framework for Java. Microbenchmarks are hard to get right, so Caliper goes out
of its way to do the hard work for you, and even detect some cases where you're
not measuring what you think you're measuring (because, say, the VM has
managed to optimize all your code away). We highly recommend you use Caliper
to run your own microbenchmarks.</p>
<p>You may also find
<a href="{@docRoot}guide/developing/tools/traceview.html">Traceview</a> useful
for profiling, but it's important to realize that it currently disables the JIT,
which may cause it to misattribute time to code that the JIT may be able to win
back. It's especially important after making changes suggested by Traceview
data to ensure that the resulting code actually runs faster when run without
Traceview.

View File

@@ -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>

View File

@@ -0,0 +1,249 @@
page.title=Designing for Seamlessness
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#drop">Don't Drop Data</a></li>
<li><a href="#expose">Don't Expose Raw Data</a></li>
<li><a href="#interrupt">Don't Interrupt the User</a></li>
<li><a href="#threads">Got a Lot to Do? Do it in a Thread</a></li>
<li><a href="#multiple-activities">Don't Overload a Single Activity Screen</a></li>
<li><a href="#themes">Extend System Themes</a></li>
<li><a href="#flexui">Design Your UI to Work with Multiple Screen Resolutions</a></li>
<li><a href="#network">Assume the Network is Slow</a></li>
<li><a href="#keyboard">Don't Assume Touchscreen or Keyboard</a></li>
<li><a href="#battery">Do Conserve the Device Battery</a></li>
</ol>
</div>
</div>
<p>Even if your application is fast and responsive, certain design decisions can
still cause problems for users &mdash; because of unplanned interactions with
other applications or dialogs, inadvertent loss of data, unintended blocking,
and so on. To avoid these problems, it helps to understand the context in which
your applications run and the system interactions that can affect your
application. In short, you should strive to develop an application that
interacts seamlessly with the system and with other applications. </p>
<p>A common seamlessness problem is when an application's background process
&mdash; for example, a service or broadcast receiver &mdash; pops up a dialog in
response to some event. This may seem like harmless behavior, especially when
you are building and testing your application in isolation, on the emulator.
However, when your application is run on an actual device, your application may
not have user focus at the time your background process displays the dialog. So
it could end up that your application would display it's dialog behind the
active application, or it could take focus from the current application and
display the dialog in front of whatever the user was doing (such as dialing a
phone call, for example). That behavior would not work for your application or
for the user. </p>
<p>To avoid these problems, your application should use the proper system
facility for notifying the user &mdash; the
{@link android.app.Notification Notification} classes. Using
notifications, your application can signal the user that an event has
taken place, by displaying an icon in the status bar rather than taking
focus and interrupting the user.</p>
<p>Another example of a seamlessness problem is when an activity inadvertently
loses state or user data because it doesn't correctly implement the onPause()
and other lifecycle methods. Or, if your application exposes data intended to be
used by other applications, you should expose it via a ContentProvider, rather
than (for example) doing so through a world-readable raw file or database.</p>
<p>What those examples have in common is that they involve cooperating nicely
with the system and other applications. The Android system is designed to treat
applications as a sort of federation of loosely-coupled components, rather than
chunks of black-box code. This allows you as the developer to view the entire
system as just an even-larger federation of these components. This benefits you
by allowing you to integrate cleanly and seamlessly with other applications, and
so you should design your own code to return the favor.</p>
<p>This document discusses common seamlessness problems and how to avoid them.</p>
<h2 id="drop">Don't Drop Data</h2>
<p>Always keep in mind that Android is a mobile platform. It may seem obvious to
say it, but it's important to remember that another Activity (such as the
"Incoming Phone Call" app) can pop up over your own Activity at any moment.
This will fire the onSaveInstanceState() and onPause() methods, and will likely result in
your application being killed.</p>
<p>If the user was editing data in your application when the other Activity
appeared, your application will likely lose that data when your application is
killed. Unless, of course, you save the work in progress first. The "Android
Way" is to do just that: Android applications that accept or edit input should
override the onSaveInstanceState() method and save their state in some appropriate
fashion. When the user revisits the application, she should be able to
retrieve her data.</p>
<p>A classic example of a good use of this behavior is a mail application. If the
user was composing an email when another Activity started up, the application
should save the in-process email as a draft.</p>
<h2 id="expose">Don't Expose Raw Data</h2>
<p>If you wouldn't walk down the street in your underwear, neither should your
data. While it's possible to expose certain kinds of application to the world
to read, this is usually not the best idea. Exposing raw data requires other
applications to understand your data format; if you change that format, you'll
break any other applications that aren't similarly updated.</p>
<p>The "Android Way" is to create a ContentProvider to expose your data to other
applications via a clean, well-thought-out, and maintainable API. Using a
ContentProvider is much like inserting a Java language interface to split up and
componentize two tightly-coupled pieces of code. This means you'll be able to
modify the internal format of your data without changing the interface exposed
by the ContentProvider, and this without affecting other applications.</p>
<h2 id="interrupt">Don't Interrupt the User</h2>
<p>If the user is running an application (such as the Phone application during a
call) it's a pretty safe bet he did it on purpose. That's why you should avoid
spawning activities except in direct response to user input from the current
Activity.</p>
<p>That is, don't call startActivity() from BroadcastReceivers or Services running in
the background. Doing so will interrupt whatever application is currently
running, and result in an annoyed user. Perhaps even worse, your Activity may
become a "keystroke bandit" and receive some of the input the user was in the
middle of providing to the previous Activity. Depending on what your
application does, this could be bad news.</p>
<p>Instead of spawning Activity UIs directly from the background, you should
instead use the NotificationManager to set Notifications. These will appear in
the status bar, and the user can then click on them at his leisure, to see
what your application has to show him.</p>
<p>(Note that all this doesn't apply to cases where your own Activity is already
in the foreground: in that case, the user expects to see your next Activity in
response to input.)</p>
<h2 id="threads">Got a Lot to Do? Do it in a Thread</h2>
<p>If your application needs to perform some expensive or long-running
computation, you should probably move it to a thread. This will prevent the
dreaded "Application Not Responding" dialog from being displayed to the user,
with the ultimate result being the fiery demise of your application.</p>
<p>By default, all code in an Activity as well as all its Views run in the same
thread. This is the same thread that also handles UI events. For example, when
the user presses a key, a key-down event is added to the Activity's main
thread's queue. The event handler system needs to dequeue and handle that
event quickly; if it doesn't, the system concludes after a few seconds that
the application is hung and offers to kill it for the user.</p>
<p>If you have long-running code, running it inline in your Activity will run it
on the event handler thread, effectively blocking the event handler. This will
delay input processing, and result in the ANR dialogs. To avoid this, move
your computations to a thread. This <a
href="responsiveness.html">Design for Responsiveness</a> document
discusses how to do that..</p>
<h2 id="multiple-activities">Don't Overload a Single Activity Screen</h2>
<p>Any application worth using will probably have several different screens.
When designing the screens of your UI, be sure to make use of multiple Activity
object instances.</p>
<p>Depending on your development background, you may interpret an Activity as
similar to something like a Java Applet, in that it is the entry point for
your application. However, that's not quite accurate: where an Applet subclass
is the single entry point for a Java Applet, an Activity should be thought of
as one of potentially several entry points to your application. The only
difference between your "main" Activity and any others you might have is that
the "main" one just happens to be the only one that expressed an interest in
the "android.intent.action.MAIN" action in your AndroidManifest..xml file.</p>
<p>So, when designing your application, think of your application as a federation
of Activity objects. This will make your code a lot more maintainable in the long
run, and as a nice side effect also plays nicely with Android's application
history and "backstack" model.</p>
<h2 id="themes">Extend System Themes</h2>
<p>When it comes to the look-and-feel of the user interface, it's important to
blend in nicely. Users are jarred by applications which contrast with the user
interface they've come to expect. When designing your UIs, you should try and
avoid rolling your own as much as possible. Instead, use a Theme. You
can override or extend those parts of the theme that you need to, but at least
you're starting from the same UI base as all the other applications. For all
the details, read <a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p>
<h2 id="flexui">Design Your UI to Work with Multiple Screen Resolutions</h2>
<p>Different Android-powered devices will support different screen resolutions.
Some will even be able to change resolutions on the fly, such as by switching
to landscape mode. It's important to make sure your layouts and drawables
are flexible enough to display properly on a variety of device screens.</p>
<p>Fortunately, this is very easy to do. In brief, what you must do is
provide different versions of your artwork (if you use any) for the key
resolutions, and then design your layout to accommodate various dimensions.
(For example, avoid using hard-coded positions and instead use relative
layouts.) If you do that much, the system handles the rest, and your
application looks great on any device.</p>
<h2 id="network">Assume the Network is Slow</h2>
<p>Android devices will come with a variety of network-connectivity options. All
will have some data-access provision, though some will be faster than others.
The lowest common denominator, however, is GPRS, the non-3G data service for
GSM networks. Even 3G-capable devices will spend lots of time on non-3G
networks, so slow networks will remain a reality for quite a long time to
come.</p>
<p>That's why you should always code your applications to minimize network
accesses and bandwidth. You can't assume the network is fast, so you should
always plan for it to be slow. If your users happen to be on faster networks,
then that's great &mdash; their experience will only improve. You want to avoid the
inverse case though: applications that are usable some of the time, but
frustratingly slow the rest based on where the user is at any given moment are
likely to be unpopular.</p>
<p>One potential gotcha here is that it's very easy to fall into this trap if
you're using the emulator, since the emulator uses your desktop computer's
network connection. That's almost guaranteed to be much faster than a cell
network, so you'll want to change the settings on the emulator that simulate
slower network speeds. You can do this in Eclipse, in the "Emulator Settings"
tab of your launch configuration or via a <a
href="{@docRoot}guide/developing/tools/emulator.html#netspeed">command-line
option</a> when starting the emulator.</p>
<h2 id="keyboard">Don't Assume Touchscreen or Keyboard</h2>
<p>
Android will support a variety of handset form-factors. That's a fancy way of
saying that some Android devices will have full "QWERTY" keyboards, while
others will have 40-key, 12-key, or even other key configurations. Similarly,
some devices will have touch-screens, but many won't.
</p><p>
When building your applications, keep that in mind. Don't make assumptions
about specific keyboard layouts -- unless, of course, you're really interested
in restricting your application so that it can only be used on those devices.
</p>
<h2 id="battery">Do Conserve the Device Battery</h2>
<p>
A mobile device isn't very mobile if it's constantly plugged into the
wall. Mobile devices are battery-powered, and the longer we can make that
battery last on a charge, the happier everyone is &mdash; especially the user.
Two of the biggest consumers of battery power are the processor, and the
radio; that's why it's important to write your applications to do as little
work as possible, and use the network as infrequently as possible.
</p><p>
Minimizing the amount of processor time your application uses really comes
down to <a href="performance.html">writing efficient
code</a>. To minimize the power drain from using the radio, be sure to handle
error conditions gracefully, and only fetch what you need. For example, don't
constantly retry a network operation if one failed. If it failed once, it's
likely because the user has no reception, so it's probably going to fail again
if you try right away; all you'll do is waste battery power.
</p><p>
Users are pretty smart: if your program is power-hungry, you can count on
them noticing. The only thing you can be sure of at that point is that your
program won't stay installed very long.
</p>