implement new organization for Training classes
This also moves a few of the documents from API Guides > Best Practices into the new courses for best practices. This is also dependent on CL Ieac8a97a8d6fda41a3682241901150cfe16afc4d which generates the list of classes/lessons on each course landing page. Change-Id: I8132f72f78d844c3b035c7aa269ad3b88a25d02a
This commit is contained in:
@@ -529,25 +529,6 @@
|
|||||||
<li><a href="<?cs var:toroot ?>guide/practices/tablets-and-handsets.html">
|
<li><a href="<?cs var:toroot ?>guide/practices/tablets-and-handsets.html">
|
||||||
<span class="en">Supporting Tablets and Handsets</span>
|
<span class="en">Supporting Tablets and Handsets</span>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li class="nav-section">
|
|
||||||
<div class="nav-section-header"><a href="<?cs var:toroot ?>guide/practices/performance.html">
|
|
||||||
<span class="en">Designing for Performance</span>
|
|
||||||
</a></div>
|
|
||||||
<ul>
|
|
||||||
<li><a href="<?cs var:toroot ?>guide/practices/jni.html">
|
|
||||||
<span class="en">JNI Tips</span>
|
|
||||||
</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a href="<?cs var:toroot ?>guide/practices/responsiveness.html">
|
|
||||||
<span class="en">Designing for Responsiveness</span>
|
|
||||||
</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>guide/practices/seamlessness.html">
|
|
||||||
<span class="en">Designing for Seamlessness</span>
|
|
||||||
</a></li>
|
|
||||||
<li><a href="<?cs var:toroot ?>guide/practices/security.html">
|
|
||||||
<span class="en">Designing for Security</span>
|
|
||||||
</a></li>
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
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 — 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 — 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>
|
|
||||||
@@ -1,410 +0,0 @@
|
|||||||
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 Unnecessary 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="#package_inner">Consider Package Instead of Private Access 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 Unnecessary 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. The
|
|
||||||
concurrent collector introduced in Gingerbread helps, but unnecessary work
|
|
||||||
should always be avoided.</p>
|
|
||||||
|
|
||||||
<p>Thus, you should avoid creating object instances you don't need to. Some
|
|
||||||
examples of things that can help:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<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>
|
|
||||||
<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. (The trade-off being that if you're only using a small
|
|
||||||
part of the original input, you'll be keeping it all around in memory
|
|
||||||
anyway if you go this route.)</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
|
|
||||||
good 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="avoid_enums" id="avoid_enums"></a>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<p>Note that if you're using ProGuard, you can have the best
|
|
||||||
of both worlds because ProGuard can inline accessors for you.</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><clinit></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><clinit></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 < 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 < 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="package_inner" id="package_inner"></a>
|
|
||||||
<h2>Consider Package Instead of Private Access with Private Inner Classes</h2>
|
|
||||||
|
|
||||||
<p>Consider the following class definition:</p>
|
|
||||||
|
|
||||||
<pre>public class Foo {
|
|
||||||
private class Inner {
|
|
||||||
void stuff() {
|
|
||||||
Foo.this.doStuff(Foo.this.mValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}</pre>
|
|
||||||
|
|
||||||
<p>The key things to note here are that we define a private inner class
|
|
||||||
(<code>Foo$Inner</code>) 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 <code>Foo</code>'s
|
|
||||||
private members from <code>Foo$Inner</code> to be illegal because
|
|
||||||
<code>Foo</code> and <code>Foo$Inner</code> 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 <code>mValue</code> field or invoke the <code>doStuff</code> 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.
|
|
||||||
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>If you're using code like this in a performance hotspot, you can avoid the
|
|
||||||
overhead by declaring fields and methods accessed by inner classes to have
|
|
||||||
package access, rather than private access. Unfortunately this means the fields
|
|
||||||
can be accessed directly by other classes in the same package, so you shouldn't
|
|
||||||
use this in public API.</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 — 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>If you do need to use native code, you should read our
|
|
||||||
<a href="{@docRoot}guide/practices/jni.html">JNI Tips</a>.</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}tools/debugging/debugging-tracing.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.
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
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 — 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 — 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>
|
|
||||||
@@ -1,767 +0,0 @@
|
|||||||
page.title=Designing for Security
|
|
||||||
@jd:body
|
|
||||||
|
|
||||||
<div id="qv-wrapper">
|
|
||||||
<div id="qv">
|
|
||||||
<h2>In this document</h2>
|
|
||||||
<ol>
|
|
||||||
<li><a href="#Dalvik">Using Davlik Code</a></li>
|
|
||||||
<li><a href="#Native">Using Native Code</a></li>
|
|
||||||
<li><a href="#Data">Storing Data</a></li>
|
|
||||||
<li><a href="#IPC">Using IPC</a></li>
|
|
||||||
<li><a href="#Permissions">Using Permissions</a></li>
|
|
||||||
<li><a href="#Networking">Using Networking</a></li>
|
|
||||||
<li><a href="#DynamicCode">Dynamically Loading Code</a></li>
|
|
||||||
<li><a href="#Input">Performing Input Validation</a></li>
|
|
||||||
<li><a href="#UserData">Handling User Data</a></li>
|
|
||||||
<li><a href="#Crypto">Using Cryptography</a></li>
|
|
||||||
</ol>
|
|
||||||
<h2>See also</h2>
|
|
||||||
<ol>
|
|
||||||
<li><a href="http://source.android.com/tech/security/index.html">Android
|
|
||||||
Security Overview</a></li>
|
|
||||||
<li><a href="{@docRoot}guide/topics/security/permissions.html">Permissions</a></li>
|
|
||||||
</ol>
|
|
||||||
</div></div>
|
|
||||||
<p>Android was designed so that most developers will be able to build
|
|
||||||
applications using the default settings and not be confronted with difficult
|
|
||||||
decisions about security. Android also has a number of security features built
|
|
||||||
into the operating system that significantly reduce the frequency and impact of
|
|
||||||
application security issues.</p>
|
|
||||||
|
|
||||||
<p>Some of the security features that help developers build secure applications
|
|
||||||
include:
|
|
||||||
<ul>
|
|
||||||
<li>The Android Application Sandbox that isolates data and code execution on a
|
|
||||||
per-application basis.</li>
|
|
||||||
<li>Android application framework with robust implementations of common
|
|
||||||
security functionality such as cryptography, permissions, and secure IPC.</li>
|
|
||||||
<li>Technologies like ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD
|
|
||||||
calloc, and Linux mmap_min_addr to mitigate risks associated with common memory
|
|
||||||
management errors</li>
|
|
||||||
<li>An encrypted filesystem that can be enabled to protect data on lost or
|
|
||||||
stolen devices.</li>
|
|
||||||
</ul></p>
|
|
||||||
|
|
||||||
<p>Nevertheless, it is important for developers to be familiar with Android
|
|
||||||
security best practices to make sure they take advantage of these capabilities
|
|
||||||
and to reduce the likelihood of inadvertently introducing security issues that
|
|
||||||
can affect their applications.</p>
|
|
||||||
|
|
||||||
<p>This document is organized around common APIs and development techniques
|
|
||||||
that can have security implications for your application and its users. As
|
|
||||||
these best practices are constantly evolving, we recommend you check back
|
|
||||||
occasionally throughout your application development process.</p>
|
|
||||||
|
|
||||||
<a name="Dalvik"></a>
|
|
||||||
<h2>Using Dalvik Code</h2>
|
|
||||||
<p>Writing secure code that runs in virtual machines is a well-studied topic
|
|
||||||
and many of the issues are not specific to Android. Rather than attempting to
|
|
||||||
rehash these topics, we’d recommend that you familiarize yourself with the
|
|
||||||
existing literature. Two of the more popular resources are:
|
|
||||||
<ul>
|
|
||||||
<li><a href="http://www.securingjava.com/toc.html">
|
|
||||||
http://www.securingjava.com/toc.html</a></li>
|
|
||||||
<li><a
|
|
||||||
href="https://www.owasp.org/index.php/Java_Security_Resources">
|
|
||||||
https://www.owasp.org/index.php/Java_Security_Resources</a></li>
|
|
||||||
</ul></p>
|
|
||||||
|
|
||||||
<p>This document is focused on the areas which are Android specific and/or
|
|
||||||
different from other environments. For developers experienced with VM
|
|
||||||
programming in other environments, there are two broad issues that may be
|
|
||||||
different about writing apps for Android:
|
|
||||||
<ul>
|
|
||||||
<li>Some virtual machines, such as the JVM or .net runtime, act as a security
|
|
||||||
boundary, isolating code from the underlying operating system capabilities. On
|
|
||||||
Android, the Dalvik VM is not a security boundary -- the application sandbox is
|
|
||||||
implemented at the OS level, so Dalvik can interoperate with native code in the
|
|
||||||
same application without any security constraints.</li>
|
|
||||||
<li>Given the limited storage on mobile devices, it’s common for developers
|
|
||||||
to want to build modular applications and use dynamic class loading. When
|
|
||||||
doing this consider both the source where you retrieve your application logic
|
|
||||||
and where you store it locally. Do not use dynamic class loading from sources
|
|
||||||
that are not verified, such as unsecured network sources or external storage,
|
|
||||||
since that code can be modified to include malicious behavior.</li>
|
|
||||||
</ul></p>
|
|
||||||
|
|
||||||
<a name="Native"></a>
|
|
||||||
<h2>Using Native Code</h2>
|
|
||||||
|
|
||||||
<p>In general, we encourage developers to use the Android SDK for most
|
|
||||||
application development, rather than using native code. Applications built
|
|
||||||
with native code are more complex, less portable, and more like to include
|
|
||||||
common memory corruption errors such as buffer overflows.</p>
|
|
||||||
|
|
||||||
<p>Android is built using the Linux kernel and being familiar with Linux
|
|
||||||
development security best practices is especially useful if you are going to
|
|
||||||
use native code. This document is too short to discuss all of those best
|
|
||||||
practices, but one of the most popular resources is “Secure Programming for
|
|
||||||
Linux and Unix HOWTO”, available at <a
|
|
||||||
href="http://www.dwheeler.com/secure-programs">
|
|
||||||
http://www.dwheeler.com/secure-programs</a>.</p>
|
|
||||||
|
|
||||||
<p>An important difference between Android and most Linux environments is the
|
|
||||||
Application Sandbox. On Android, all applications run in the Application
|
|
||||||
Sandbox, including those written with native code. At the most basic level, a
|
|
||||||
good way to think about it for developers familiar with Linux is to know that
|
|
||||||
every application is given a unique UID with very limited permissions. This is
|
|
||||||
discussed in more detail in the <a
|
|
||||||
href="http://source.android.com/tech/security/index.html">Android Security
|
|
||||||
Overview</a> and you should be familiar with application permissions even if
|
|
||||||
you are using native code.</p>
|
|
||||||
|
|
||||||
<a name="Data"></a>
|
|
||||||
<h2>Storing Data</h2>
|
|
||||||
|
|
||||||
<h3>Using internal files</h3>
|
|
||||||
|
|
||||||
<p>By default, files created on <a
|
|
||||||
href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal
|
|
||||||
storage</a> are only accessible to the application that created the file. This
|
|
||||||
protection is implemented by Android and is sufficient for most
|
|
||||||
applications.</p>
|
|
||||||
|
|
||||||
<p>Use of <a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#MODE_WORLD_WRITEABLE">
|
|
||||||
world writable</a> or <a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#MODE_WORLD_READABLE">world
|
|
||||||
readable</a> files for IPC is discouraged because it does not provide
|
|
||||||
the ability to limit data access to particular applications, nor does it
|
|
||||||
provide any control on data format. As an alternative, you might consider using
|
|
||||||
a ContentProvider which provides read and write permissions, and can make
|
|
||||||
dynamic permission grants on a case-by-case basis.</p>
|
|
||||||
|
|
||||||
<p>To provide additional protection for sensitive data, some applications
|
|
||||||
choose to encrypt local files using a key that is not accessible to the
|
|
||||||
application. (For example, a key can be placed in a {@link java.security.KeyStore}
|
|
||||||
and protected with a user password that is not stored on the device). While this
|
|
||||||
does not protect data from a root compromise that can monitor the user
|
|
||||||
inputting the password, it can provide protection for a lost device without <a
|
|
||||||
href="http://source.android.com/tech/encryption/index.html">file system
|
|
||||||
encryption</a>.</p>
|
|
||||||
|
|
||||||
<h3>Using external storage</h3>
|
|
||||||
|
|
||||||
<p>Files created on <a
|
|
||||||
href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">external
|
|
||||||
storage</a>, such as SD Cards, are globally readable and writable. Since
|
|
||||||
external storage can be removed by the user and also modified by any
|
|
||||||
application, applications should not store sensitive information using
|
|
||||||
external storage.</p>
|
|
||||||
|
|
||||||
<p>As with data from any untrusted source, applications should perform input
|
|
||||||
validation when handling data from external storage (see Input Validation
|
|
||||||
section). We strongly recommend that applications not store executables or
|
|
||||||
class files on external storage prior to dynamic loading. If an application
|
|
||||||
does retrieve executable files from external storage they should be signed and
|
|
||||||
cryptographically verified prior to dynamic loading.</p>
|
|
||||||
|
|
||||||
<h3>Using content providers</h3>
|
|
||||||
|
|
||||||
<p>ContentProviders provide a structured storage mechanism that can be limited
|
|
||||||
to your own application, or exported to allow access by other applications. By
|
|
||||||
default, a <code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html">
|
|
||||||
ContentProvider</a></code> is
|
|
||||||
<a href="{@docRoot}guide/topics/manifest/provider-element.html#exported">exported
|
|
||||||
</a> for use by other applications. If you do not intend to provide other
|
|
||||||
applications with access to your<code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html">
|
|
||||||
ContentProvider</a></code>, mark them as <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
|
|
||||||
android:exported=false</a></code> in the application manifest.</p>
|
|
||||||
|
|
||||||
<p>When creating a <code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html">ContentProvider
|
|
||||||
</a></code> that will be exported for use by other applications, you can specify
|
|
||||||
a single
|
|
||||||
<a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">permission
|
|
||||||
</a> for reading and writing, or distinct permissions for reading and writing
|
|
||||||
within the manifest. We recommend that you limit your permissions to those
|
|
||||||
required to accomplish the task at hand. Keep in mind that it’s usually
|
|
||||||
easier to add permissions later to expose new functionality than it is to take
|
|
||||||
them away and break existing users.</p>
|
|
||||||
|
|
||||||
<p>If you are using a <code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html">
|
|
||||||
ContentProvider</a></code> for sharing data between applications built by the
|
|
||||||
same developer, it is preferable to use
|
|
||||||
<a href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
|
|
||||||
level permissions</a>. Signature permissions do not require user confirmation,
|
|
||||||
so they provide a better user experience and more controlled access to the
|
|
||||||
<code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html">
|
|
||||||
ContentProvider</a></code>.</p>
|
|
||||||
|
|
||||||
<p>ContentProviders can also provide more granular access by declaring the <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
|
|
||||||
grantUriPermissions</a> element and using the <code><a
|
|
||||||
href="{@docRoot}reference/android/content/Intent.html#FLAG_GRANT_READ_URI_PERMISSION">FLAG_GRANT_READ_URI_PERMISSION</a></code>
|
|
||||||
and <code><a
|
|
||||||
href="{@docRoot}reference/android/content/Intent.html#FLAG_GRANT_WRITE_URI_PERMISSION">FLAG_GRANT_WRITE_URI_PERMISSION</a></code>
|
|
||||||
flags in the Intent object
|
|
||||||
that activates the component. The scope of these permissions can be further
|
|
||||||
limited by the <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
|
|
||||||
grant-uri-permission element</a></code>.</p>
|
|
||||||
|
|
||||||
<p>When accessing a <code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html">
|
|
||||||
ContentProvider</a></code>, use parameterized query methods such as <code>
|
|
||||||
<a href="{@docRoot}reference/android/content/ContentProvider.html#query(android.net.Uri,%20java.lang.String[],%20java.lang.String,%20java.lang.String[],%20java.lang.String)">query()</a></code>, <code><a
|
|
||||||
href="{@docRoot}reference/android/content/ContentProvider.html#update(android.net.Uri,%20android.content.ContentValues,%20java.lang.String,%20java.lang.String[])">update()</a></code>, and <code><a
|
|
||||||
href="{@docRoot}reference/android/content/ContentProvider.html#delete(android.net.Uri,%20java.lang.String,%20java.lang.String[])">delete()</a></code> to avoid
|
|
||||||
potential <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL
|
|
||||||
Injection</a> from untrusted data. Note that using parameterized methods is not
|
|
||||||
sufficient if the <code>selection</code> is built by concatenating user data
|
|
||||||
prior to submitting it to the method.</p>
|
|
||||||
|
|
||||||
<p>Do not have a false sense of security about the write permission. Consider
|
|
||||||
that the write permission allows SQL statements which make it possible for some
|
|
||||||
data to be confirmed using creative <code>WHERE</code> clauses and parsing the
|
|
||||||
results. For example, an attacker might probe for presence of a specific phone
|
|
||||||
number in a call-log by modifying a row only if that phone number already
|
|
||||||
exists. If the content provider data has predictable structure, the write
|
|
||||||
permission may be equivalent to providing both reading and writing.</p>
|
|
||||||
|
|
||||||
<a name="IPC"></a>
|
|
||||||
<h2>Using Interprocess Communication (IPC)</h2>
|
|
||||||
|
|
||||||
<p>Some Android applications attempt to implement IPC using traditional Linux
|
|
||||||
techniques such as network sockets and shared files. We strongly encourage the
|
|
||||||
use of Android system functionality for IPC such as Intents, Binders, Services,
|
|
||||||
and Receivers. The Android IPC mechanisms allow you to verify the identity of
|
|
||||||
the application connecting to your IPC and set security policy for each IPC
|
|
||||||
mechanism.</p>
|
|
||||||
|
|
||||||
<p>Many of the security elements are shared across IPC mechanisms. <a
|
|
||||||
href="{@docRoot}reference/android/content/BroadcastReceiver.html">
|
|
||||||
Broadcast Receivers</a>, <a
|
|
||||||
href="{@docRoot}reference/android/R.styleable.html#AndroidManifestActivity">
|
|
||||||
Activities</a>, and <a
|
|
||||||
href="{@docRoot}reference/android/R.styleable.html#AndroidManifestService">
|
|
||||||
Services</a> are all declared in the application manifest. If your IPC mechanism is
|
|
||||||
not intended for use by other applications, set the <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
|
|
||||||
property to false. This is useful for applications that consist of multiple processes
|
|
||||||
within the same UID, or if you decide late in development that you do not
|
|
||||||
actually want to expose functionality as IPC but you don’t want to rewrite
|
|
||||||
the code.</p>
|
|
||||||
|
|
||||||
<p>If your IPC is intended to be accessible to other applications, you can
|
|
||||||
apply a security policy by using the <a
|
|
||||||
href="{@docRoot}reference/android/R.styleable.html#AndroidManifestPermission">
|
|
||||||
Permission</a> tag. If IPC is between applications built by the same developer,
|
|
||||||
it is preferable to use <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
|
|
||||||
level permissions</a>. Signature permissions do not require user confirmation,
|
|
||||||
so they provide a better user experience and more controlled access to the IPC
|
|
||||||
mechanism.</p>
|
|
||||||
|
|
||||||
<p>One area that can introduce confusion is the use of intent filters. Note
|
|
||||||
that Intent filters should not be considered a security feature -- components
|
|
||||||
can be invoked directly and may not have data that would conform to the intent
|
|
||||||
filter. You should perform input validation within your intent receiver to
|
|
||||||
confirm that it is properly formatted for the invoked receiver, service, or
|
|
||||||
activity.</p>
|
|
||||||
|
|
||||||
<h3>Using intents</h3>
|
|
||||||
|
|
||||||
<p>Intents are the preferred mechanism for asynchronous IPC in Android.
|
|
||||||
Depending on your application requirements, you might use <code><a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#sendBroadcast(android.content.Intent)">sendBroadcast()</a></code>,
|
|
||||||
<code><a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#sendOrderedBroadcast(android.content.Intent,%20java.lang.String)">sendOrderedBroadcast()</a></code>,
|
|
||||||
or direct an intent to a specific application component.</p>
|
|
||||||
|
|
||||||
<p>Note that ordered broadcasts can be “consumed” by a recipient, so they
|
|
||||||
may not be delivered to all applications. If you are sending an Intent where
|
|
||||||
delivery to a specific receiver is required, the intent must be delivered
|
|
||||||
directly to the receiver.</p>
|
|
||||||
|
|
||||||
<p>Senders of an intent can verify that the recipient has a permission
|
|
||||||
specifying a non-Null Permission upon sending. Only applications with that
|
|
||||||
Permission will receive the intent. If data within a broadcast intent may be
|
|
||||||
sensitive, you should consider applying a permission to make sure that
|
|
||||||
malicious applications cannot register to receive those messages without
|
|
||||||
appropriate permissions. In those circumstances, you may also consider
|
|
||||||
invoking the receiver directly, rather than raising a broadcast.</p>
|
|
||||||
|
|
||||||
<h3>Using binder and AIDL interfaces</h3>
|
|
||||||
|
|
||||||
<p><a href="{@docRoot}reference/android/os/Binder.html">Binders</a> are the
|
|
||||||
preferred mechanism for RPC-style IPC in Android. They provide a well-defined
|
|
||||||
interface that enables mutual authentication of the endpoints, if required.</p>
|
|
||||||
|
|
||||||
<p>We strongly encourage designing interfaces in a manner that does not require
|
|
||||||
interface specific permission checks. Binders are not declared within the
|
|
||||||
application manifest, and therefore you cannot apply declarative permissions
|
|
||||||
directly to a Binder. Binders generally inherit permissions declared in the
|
|
||||||
application manifest for the Service or Activity within which they are
|
|
||||||
implemented. If you are creating an interface that requires authentication
|
|
||||||
and/or access controls on a specific binder interface, those controls must be
|
|
||||||
explicitly added as code in the interface.</p>
|
|
||||||
|
|
||||||
<p>If providing an interface that does require access controls, use <code><a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#checkCallingPermission(java.lang.String)">checkCallingPermission()</a></code>
|
|
||||||
to verify whether the
|
|
||||||
caller of the Binder has a required permission. This is especially important
|
|
||||||
before accessing a Service on behalf of the caller, as the identify of your
|
|
||||||
application is passed to other interfaces. If invoking an interface provided
|
|
||||||
by a Service, the <code><a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#bindService(android.content.Intent,%20android.content.ServiceConnection,%20int)">bindService()</a></code>
|
|
||||||
invocation may fail if you do not have permission to access the given Service.
|
|
||||||
If calling an interface provided locally by your own application, it may be
|
|
||||||
useful to use the <code><a
|
|
||||||
href="{@docRoot}reference/android/os/Binder.html#clearCallingIdentity()">
|
|
||||||
clearCallingIdentity()</a></code> to satisfy internal security checks.</p>
|
|
||||||
|
|
||||||
<h3>Using broadcast receivers</h3>
|
|
||||||
|
|
||||||
<p>Broadcast receivers are used to handle asynchronous requests initiated via
|
|
||||||
an intent.</p>
|
|
||||||
|
|
||||||
<p>By default, receivers are exported and can be invoked by any other
|
|
||||||
application. If your <code><a
|
|
||||||
href="{@docRoot}reference/android/content/BroadcastReceiver.html">
|
|
||||||
BroadcastReceivers</a></code> is intended for use by other applications, you
|
|
||||||
may want to apply security permissions to receivers using the <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/receiver-element.html">
|
|
||||||
<receiver></a></code> element within the application manifest. This will
|
|
||||||
prevent applications without appropriate permissions from sending an intent to
|
|
||||||
the <code><a
|
|
||||||
href="{@docRoot}reference/android/content/BroadcastReceiver.html">
|
|
||||||
BroadcastReceivers</a></code>.</p>
|
|
||||||
|
|
||||||
<h3>Using Services</h3>
|
|
||||||
|
|
||||||
<p>Services are often used to supply functionality for other applications to
|
|
||||||
use. Each service class must have a corresponding <service> declaration in its
|
|
||||||
package's AndroidManifest.xml.</p>
|
|
||||||
|
|
||||||
<p>By default, Services are exported and can be invoked by any other
|
|
||||||
application. Services can be protected using the <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/service-element.html#prmsn">{@code android:permission}</a>
|
|
||||||
attribute
|
|
||||||
within the manifest’s <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/service-element.html">
|
|
||||||
<service></a></code> tag. By doing so, other applications will need to declare
|
|
||||||
a corresponding <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a>
|
|
||||||
</code> element in their own manifest to be
|
|
||||||
able to start, stop, or bind to the service.</p>
|
|
||||||
|
|
||||||
<p>A Service can protect individual IPC calls into it with permissions, by
|
|
||||||
calling <code><a
|
|
||||||
href="{@docRoot}reference/android/content/Context.html#checkCallingPermission(java.lang.String)">checkCallingPermission()</a></code>
|
|
||||||
before executing
|
|
||||||
the implementation of that call. We generally recommend using the
|
|
||||||
declarative permissions in the manifest, since those are less prone to
|
|
||||||
oversight.</p>
|
|
||||||
|
|
||||||
<h3>Using Activities</h3>
|
|
||||||
|
|
||||||
<p>Activities are most often used for providing the core user-facing
|
|
||||||
functionality of an application. By default, Activities are exported and
|
|
||||||
invokable by other applications only if they have an intent filter or binder
|
|
||||||
declared. In general, we recommend that you specifically declare a Receiver or
|
|
||||||
Service to handle IPC, since this modular approach reduces the risk of exposing
|
|
||||||
functionality that is not intended for use by other applications.</p>
|
|
||||||
|
|
||||||
<p>If you do expose an Activity for purposes of IPC, the <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/activity-element.html#prmsn">android:permission</a></code>
|
|
||||||
attribute in the <code><a
|
|
||||||
href="{@docRoot}guide/topics/manifest/activity-element.html">
|
|
||||||
<activity></a></code> declaration in the application manifest can be used to
|
|
||||||
restrict access to only those applications which have the stated
|
|
||||||
permissions.</p>
|
|
||||||
|
|
||||||
<a name="Permissions"></a>
|
|
||||||
<h2>Using Permissions</h2>
|
|
||||||
|
|
||||||
<h3>Requesting Permissions</h3>
|
|
||||||
|
|
||||||
<p>We recommend minimizing the number of permissions requested by an
|
|
||||||
application. Not having access to sensitive permissions reduces the risk of
|
|
||||||
inadvertently misusing those permissions, can improve user adoption, and makes
|
|
||||||
applications less attractive targets for attackers.</p>
|
|
||||||
|
|
||||||
<p>If it is possible to design your application in a way that does not require
|
|
||||||
a permission, that is preferable. For example, rather than requesting access
|
|
||||||
to device information to create an identifier, create a <a
|
|
||||||
href="{@docRoot}reference/java/util/UUID.html">GUID</a> for your application.
|
|
||||||
(This specific example is also discussed in Handling User Data) Or, rather than
|
|
||||||
using external storage, store data in your application directory.</p>
|
|
||||||
|
|
||||||
<p>If a permission is not required, do not request it. This sounds simple, but
|
|
||||||
there has been quite a bit of research into the frequency of over-requesting
|
|
||||||
permissions. If you’re interested in the subject you might start with this
|
|
||||||
research paper published by U.C. Berkeley: <a
|
|
||||||
href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2011/EECS-2011-48.pdf">
|
|
||||||
http://www.eecs.berkeley.edu/Pubs/TechRpts/2011/EECS-2011-48.pdf</a></p>
|
|
||||||
|
|
||||||
<p>In addition to requesting permissions, your application can use <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/permission-element.html">permissions</a>
|
|
||||||
to protect IPC that is security sensitive and will be exposed to other
|
|
||||||
applications -- such as a <code><a
|
|
||||||
href="{@docRoot}reference/android/content/ContentProvider.html">
|
|
||||||
ContentProvider</a></code>. In general, we recommend using access controls
|
|
||||||
other than user confirmed permissions where possible since permissions can
|
|
||||||
be confusing for users. For example, consider using the <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
|
|
||||||
protection level</a> on permissions for IPC communication between applications
|
|
||||||
provided by a single developer.</p>
|
|
||||||
|
|
||||||
<p>Do not cause permission re-delegation. This occurs when an app exposes data
|
|
||||||
over IPC that is only available because it has a specific permission, but does
|
|
||||||
not require that permission of any clients of it’s IPC interface. More
|
|
||||||
details on the potential impacts, and frequency of this type of problem is
|
|
||||||
provided in this research paper published at USENIX: <a
|
|
||||||
href="http://www.cs.berkeley.edu/~afelt/felt_usenixsec2011.pdf">http://www.cs.be
|
|
||||||
rkeley.edu/~afelt/felt_usenixsec2011.pdf</a></p>
|
|
||||||
|
|
||||||
<h3>Creating Permissions</h3>
|
|
||||||
|
|
||||||
<p>Generally, you should strive to create as few permissions as possible while
|
|
||||||
satisfying your security requirements. Creating a new permission is relatively
|
|
||||||
uncommon for most applications, since <a
|
|
||||||
href="{@docRoot}reference/android/Manifest.permission.html">system-defined
|
|
||||||
permissions</a> cover many situations. Where appropriate,
|
|
||||||
perform access checks using existing permissions.</p>
|
|
||||||
|
|
||||||
<p>If you must create a new permission, consider whether you can accomplish
|
|
||||||
your task with a Signature permission. Signature permissions are transparent
|
|
||||||
to the user and only allow access by applications signed by the same developer
|
|
||||||
as application performing the permission check. If you create a Dangerous
|
|
||||||
permission, then the user needs to decide whether to install the application.
|
|
||||||
This can be confusing for other developers, as well as for users.</p>
|
|
||||||
|
|
||||||
<p>If you create a Dangerous permission, there are a number of complexities
|
|
||||||
that you need to consider.
|
|
||||||
<ul>
|
|
||||||
<li>The permission must have a string that concisely expresses to a user the
|
|
||||||
security decision they will be required to make.</li>
|
|
||||||
<li>The permission string must be localized to many different languages.</li>
|
|
||||||
<li>Uses may choose not to install an application because a permission is
|
|
||||||
confusing or perceived as risky.</li>
|
|
||||||
<li>Applications may request the permission when the creator of the permission
|
|
||||||
has not been installed.</li>
|
|
||||||
</ul></p>
|
|
||||||
|
|
||||||
<p>Each of these poses a significant non-technical challenge for an application
|
|
||||||
developer, which is why we discourage the use of Dangerous permission.</p>
|
|
||||||
|
|
||||||
<a name="Networking"></a>
|
|
||||||
<h2>Using Networking</h2>
|
|
||||||
|
|
||||||
<h3>Using IP Networking</h3>
|
|
||||||
|
|
||||||
<p>Networking on Android is not significantly different from Linux
|
|
||||||
environments. The key consideration is making sure that appropriate protocols
|
|
||||||
are used for sensitive data, such as <a
|
|
||||||
href="{@docRoot}reference/javax/net/ssl/HttpsURLConnection.html">HTTPS</a> for
|
|
||||||
web traffic. We prefer use of HTTPS over HTTP anywhere that HTTPS is
|
|
||||||
supported on the server, since mobile devices frequently connect on networks
|
|
||||||
that are not secured, such as public WiFi hotspots.</p>
|
|
||||||
|
|
||||||
<p>Authenticated, encrypted socket-level communication can be easily
|
|
||||||
implemented using the <code><a
|
|
||||||
href="{@docRoot}reference/javax/net/ssl/SSLSocket.html">SSLSocket</a></code>
|
|
||||||
class. Given the frequency with which Android devices connect to unsecured
|
|
||||||
wireless networks using WiFi, the use of secure networking is strongly
|
|
||||||
encouraged for all applications.</p>
|
|
||||||
|
|
||||||
<p>We have seen some applications use <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Localhost">localhost</a> network ports for
|
|
||||||
handling sensitive IPC. We discourage this approach since these interfaces are
|
|
||||||
accessible by other applications on the device. Instead, use an Android IPC
|
|
||||||
mechanism where authentication is possible such as a Service and Binder. (Even
|
|
||||||
worse than using loopback is to bind to INADDR_ANY since then your application
|
|
||||||
may receive requests from anywhere. We’ve seen that, too.)</p>
|
|
||||||
|
|
||||||
<p>Also, one common issue that warrants repeating is to make sure that you do
|
|
||||||
not trust data downloaded from HTTP or other insecure protocols. This includes
|
|
||||||
validation of input in <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code> and
|
|
||||||
any responses to intents issued against HTTP.</p>
|
|
||||||
|
|
||||||
<h3>Using Telephony Networking</h3>
|
|
||||||
|
|
||||||
<p>SMS is the telephony protocol most frequently used by Android developers.
|
|
||||||
Developers should keep in mind that this protocol was primarily designed for
|
|
||||||
user-to-user communication and is not well-suited for some application
|
|
||||||
purposes. Due to the limitations of SMS, we strongly recommend the use of <a
|
|
||||||
href="http://code.google.com/android/c2dm/">C2DM</a> and IP networking for
|
|
||||||
sending data messages to devices.</p>
|
|
||||||
|
|
||||||
<p>Many developers do not realize that SMS is not encrypted or strongly
|
|
||||||
authenticated on the network or on the device. In particular, any SMS receiver
|
|
||||||
should expect that a malicious user may have sent the SMS to your application
|
|
||||||
-- do not rely on unauthenticated SMS data to perform sensitive commands.
|
|
||||||
Also, you should be aware that SMS may be subject to spoofing and/or
|
|
||||||
interception on the network. On the Android-powered device itself, SMS
|
|
||||||
messages are transmitted as Broadcast intents, so they may be read or captured
|
|
||||||
by other applications that have the READ_SMS permission.</p>
|
|
||||||
|
|
||||||
<a name="DynamicCode"></a>
|
|
||||||
<h2>Dynamically Loading Code</h2>
|
|
||||||
|
|
||||||
<p>We strongly discourage loading code from outside of the application APK.
|
|
||||||
Doing so significantly increases the likelihood of application compromise due
|
|
||||||
to code injection or code tampering. It also adds complexity around version
|
|
||||||
management and application testing. Finally, it can make it impossible to
|
|
||||||
verify the behavior of an application, so it may be prohibited in some
|
|
||||||
environments.</p>
|
|
||||||
|
|
||||||
<p>If your application does dynamically load code, the most important thing to
|
|
||||||
keep in mind about dynamically loaded code is that it runs with the same
|
|
||||||
security permissions as the application APK. The user made a decision to
|
|
||||||
install your application based on your identity, and they are expecting that
|
|
||||||
you provide any code run within the application, including code that is
|
|
||||||
dynamically loaded.</p>
|
|
||||||
|
|
||||||
<p>The major security risk associated with dynamically loading code is that the
|
|
||||||
code needs to come from a verifiable source. If the modules are included
|
|
||||||
directly within your APK, then they cannot be modified by other applications.
|
|
||||||
This is true whether the code is a native library or a class being loaded using
|
|
||||||
<a href="{@docRoot}reference/dalvik/system/DexClassLoader.html">
|
|
||||||
<code>DexClassLoader</code></a>. We have seen many instances of applications
|
|
||||||
attempting to load code from insecure locations, such as downloaded from the
|
|
||||||
network over unencrypted protocols or from world writable locations such as
|
|
||||||
external storage. These locations could allow someone on the network to modify
|
|
||||||
the content in transit, or another application on a users device to modify the
|
|
||||||
content, respectively.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Using WebView</h3>
|
|
||||||
|
|
||||||
<p>Since WebView consumes web content that can include HTML and JavaScript,
|
|
||||||
improper use can introduce common web security issues such as <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Cross_site_scripting">cross-site-scripting</a
|
|
||||||
> (JavaScript injection). Android includes a number of mechanisms to reduce
|
|
||||||
the scope of these potential issues by limiting the capability of WebView to
|
|
||||||
the minimum functionality required by your application.</p>
|
|
||||||
|
|
||||||
<p>If your application does not directly use JavaScript within a <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, do
|
|
||||||
not call
|
|
||||||
<a href="{@docRoot}reference/android/webkit/WebSettings.html#setJavaScriptEnabled(boolean)">
|
|
||||||
<code>setJavaScriptEnabled()</code></a>. We have seen this method invoked
|
|
||||||
in sample code that might be repurposed in production application -- so
|
|
||||||
remove it if necessary. By default, <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code> does
|
|
||||||
not execute JavaScript so cross-site-scripting is not possible.</p>
|
|
||||||
|
|
||||||
<p>Use <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> with
|
|
||||||
particular care because it allows JavaScript to invoke operations that are
|
|
||||||
normally reserved for Android applications. Only expose <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> to
|
|
||||||
sources from which all input is trustworthy. If untrusted input is allowed,
|
|
||||||
untrusted JavaScript may be able to invoke Android methods. In general, we
|
|
||||||
recommend only exposing <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> to
|
|
||||||
JavaScript that is contained within your application APK.</p>
|
|
||||||
|
|
||||||
<p>Do not trust information downloaded over HTTP, use HTTPS instead. Even if
|
|
||||||
you are connecting only to a single website that you trust or control, HTTP is
|
|
||||||
subject to <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">MiTM</a> attacks
|
|
||||||
and interception of data. Sensitive capabilities using <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> should
|
|
||||||
not ever be exposed to unverified script downloaded over HTTP. Note that even
|
|
||||||
with the use of HTTPS,
|
|
||||||
<code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code>
|
|
||||||
increases the attack surface of your application to include the server
|
|
||||||
infrastructure and all CAs trusted by the Android-powered device.</p>
|
|
||||||
|
|
||||||
<p>If your application accesses sensitive data with a <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, you
|
|
||||||
may want to use the <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html#clearCache(boolean)">
|
|
||||||
clearCache()</a></code> method to delete any files stored locally. Server side
|
|
||||||
headers like no-cache can also be used to indicate that an application should
|
|
||||||
not cache particular content.</p>
|
|
||||||
|
|
||||||
<a name="Input"></a>
|
|
||||||
<h2>Performing Input Validation</h2>
|
|
||||||
|
|
||||||
<p>Insufficient input validation is one of the most common security problems
|
|
||||||
affecting applications, regardless of what platform they run on. Android does
|
|
||||||
have platform-level countermeasures that reduce the exposure of applications to
|
|
||||||
input validation issues, you should use those features where possible. Also
|
|
||||||
note that selection of type-safe languages tends to reduce the likelihood of
|
|
||||||
input validation issues. We strongly recommend building your applications with
|
|
||||||
the Android SDK.</p>
|
|
||||||
|
|
||||||
<p>If you are using native code, then any data read from files, received over
|
|
||||||
the network, or received from an IPC has the potential to introduce a security
|
|
||||||
issue. The most common problems are <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Buffer_overflow">buffer overflows</a>, <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Double_free#Use_after_free">use after
|
|
||||||
free</a>, and <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Off-by-one_error">off-by-one errors</a>.
|
|
||||||
Android provides a number of technologies like ASLR and DEP that reduce the
|
|
||||||
exploitability of these errors, but they do not solve the underlying problem.
|
|
||||||
These can be prevented by careful handling of pointers and managing of
|
|
||||||
buffers.</p>
|
|
||||||
|
|
||||||
<p>Dynamic, string based languages such as JavaScript and SQL are also subject
|
|
||||||
to input validation problems due to escape characters and <a
|
|
||||||
href="http://en.wikipedia.org/wiki/Code_injection">script injection</a>.</p>
|
|
||||||
|
|
||||||
<p>If you are using data within queries that are submitted to SQL Database or a
|
|
||||||
Content Provider, SQL Injection may be an issue. The best defense is to use
|
|
||||||
parameterized queries, as is discussed in the ContentProviders section.
|
|
||||||
Limiting permissions to read-only or write-only can also reduce the potential
|
|
||||||
for harm related to SQL Injection.</p>
|
|
||||||
|
|
||||||
<p>If you are using <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, then
|
|
||||||
you must consider the possibility of XSS. If your application does not
|
|
||||||
directly use JavaScript within a <code><a
|
|
||||||
href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, do
|
|
||||||
not call setJavaScriptEnabled() and XSS is no longer possible. If you must
|
|
||||||
enable JavaScript then the WebView section provides other security best
|
|
||||||
practices.</p>
|
|
||||||
|
|
||||||
<p>If you cannot use the security features above, we strongly recommend the use
|
|
||||||
of well-structured data formats and verifying that the data conforms to the
|
|
||||||
expected format. While blacklisting of characters or character-replacement can
|
|
||||||
be an effective strategy, these techniques are error-prone in practice and
|
|
||||||
should be avoided when possible.</p>
|
|
||||||
|
|
||||||
<a name="UserData"></a>
|
|
||||||
<h2>Handling User Data</h2>
|
|
||||||
|
|
||||||
<p>In general, the best approach is to minimize use of APIs that access
|
|
||||||
sensitive or personal user data. If you have access to data and can avoid
|
|
||||||
storing or transmitting the information, do not store or transmit the data.
|
|
||||||
Finally, consider if there is a way that your application logic can be
|
|
||||||
implemented using a hash or non-reversible form of the data. For example, your
|
|
||||||
application might use the hash of an an email address as a primary key, to
|
|
||||||
avoid transmitting or storing the email address. This reduces the chances of
|
|
||||||
inadvertently exposing data, and it also reduces the chance of attackers
|
|
||||||
attempting to exploit your application.</p>
|
|
||||||
|
|
||||||
<p>If your application accesses personal information such as passwords or
|
|
||||||
usernames, keep in mind that some jurisdictions may require you to provide a
|
|
||||||
privacy policy explaining your use and storage of that data. So following the
|
|
||||||
security best practice of minimizing access to user data may also simplify
|
|
||||||
compliance.</p>
|
|
||||||
|
|
||||||
<p>You should also consider whether your application might be inadvertently
|
|
||||||
exposing personal information to other parties such as third-party components
|
|
||||||
for advertising or third-party services used by your application. If you don't
|
|
||||||
know why a component or service requires a personal information, don’t
|
|
||||||
provide it. In general, reducing the access to personal information by your
|
|
||||||
application will reduce the potential for problems in this area.</p>
|
|
||||||
|
|
||||||
<p>If access to sensitive data is required, evaluate whether that information
|
|
||||||
must be transmitted to a server, or whether the operation can be performed on
|
|
||||||
the client. Consider running any code using sensitive data on the client to
|
|
||||||
avoid transmitting user data.</p>
|
|
||||||
|
|
||||||
<p>Also, make sure that you do not inadvertently expose user data to other
|
|
||||||
application on the device through overly permissive IPC, world writable files,
|
|
||||||
or network sockets. This is a special case of permission redelegation,
|
|
||||||
discussed in the Requesting Permissions section.</p>
|
|
||||||
|
|
||||||
<p>If a GUID is required, create a large, unique number and store it. Do not
|
|
||||||
use phone identifiers such as the phone number or IMEI which may be associated
|
|
||||||
with personal information. This topic is discussed in more detail in the <a
|
|
||||||
href="http://android-developers.blogspot.com/2011/03/identifying-app-installations.html">Android Developer Blog</a>.</p>
|
|
||||||
|
|
||||||
<p>Application developers should be careful writing to on-device logs.
|
|
||||||
In Android, logs are a shared resource, and are available
|
|
||||||
to an application with the
|
|
||||||
<a href="{@docRoot}reference/android/Manifest.permission.html#READ_LOGS">
|
|
||||||
<code>READ_LOGS</code></a> permission. Even though the phone log data
|
|
||||||
is temporary and erased on reboot, inappropriate logging of user information
|
|
||||||
could inadvertently leak user data to other applications.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Handling Credentials</h3>
|
|
||||||
|
|
||||||
<p>In general, we recommend minimizing the frequency of asking for user
|
|
||||||
credentials -- to make phishing attacks more conspicuous, and less likely to be
|
|
||||||
successful. Instead use an authorization token and refresh it.</p>
|
|
||||||
|
|
||||||
<p>Where possible, username and password should not be stored on the device.
|
|
||||||
Instead, perform initial authentication using the username and password
|
|
||||||
supplied by the user, and then use a short-lived, service-specific
|
|
||||||
authorization token.</p>
|
|
||||||
|
|
||||||
<p>Services that will be accessible to multiple applications should be accessed
|
|
||||||
using <code>
|
|
||||||
<a href="{@docRoot}reference/android/accounts/AccountManager.html">
|
|
||||||
AccountManager</a></code>. If possible, use the <code><a
|
|
||||||
href="{@docRoot}reference/android/accounts/AccountManager.html">
|
|
||||||
AccountManager</a></code> class to invoke a cloud-based service and do not store
|
|
||||||
passwords on the device.</p>
|
|
||||||
|
|
||||||
<p>After using <code><a
|
|
||||||
href="{@docRoot}reference/android/accounts/AccountManager.html">
|
|
||||||
AccountManager</a></code> to retrieve an Account, check the <code><a
|
|
||||||
href="{@docRoot}reference/android/accounts/Account.html#CREATOR">CREATOR</a>
|
|
||||||
</code> before passing in any credentials, so that you do not inadvertently pass
|
|
||||||
credentials to the wrong application.</p>
|
|
||||||
|
|
||||||
<p>If credentials are to be used only by applications that you create, then you
|
|
||||||
can verify the application which accesses the <code><a
|
|
||||||
href="{@docRoot}reference/android/accounts/AccountManager.html">
|
|
||||||
AccountManager</a></code> using <code><a
|
|
||||||
href="{@docRoot}reference/android/content/pm/PackageManager.html#checkSignatures(java.lang.String,%20java.lang.String)">checkSignature()</a></code>.
|
|
||||||
Alternatively, if only one application will use the credential, you might use a
|
|
||||||
{@link java.security.KeyStore} for
|
|
||||||
storage.</p>
|
|
||||||
|
|
||||||
<a name="Crypto"></a>
|
|
||||||
<h2>Using Cryptography</h2>
|
|
||||||
|
|
||||||
<p>In addition to providing data isolation, supporting full-filesystem
|
|
||||||
encryption, and providing secure communications channels Android provides a
|
|
||||||
wide array of algorithms for protecting data using cryptography.</p>
|
|
||||||
|
|
||||||
<p>In general, try to use the highest level of pre-existing framework
|
|
||||||
implementation that can support your use case. If you need to securely
|
|
||||||
retrieve a file from a known location, a simple HTTPS URI may be adequate and
|
|
||||||
require no knowledge of cryptography on your part. If you need a secure
|
|
||||||
tunnel, consider using
|
|
||||||
<a href="{@docRoot}reference/javax/net/ssl/HttpsURLConnection.html">
|
|
||||||
<code>HttpsURLConnection</code></a> or <code><a
|
|
||||||
href="{@docRoot}reference/javax/net/ssl/SSLSocket.html">SSLSocket</a></code>,
|
|
||||||
rather than writing your own protocol.</p>
|
|
||||||
|
|
||||||
<p>If you do find yourself needing to implement your own protocol, we strongly
|
|
||||||
recommend that you not implement your own cryptographic algorithms. Use
|
|
||||||
existing cryptographic algorithms such as those in the implementation of AES or
|
|
||||||
RSA provided in the <code><a
|
|
||||||
href="{@docRoot}reference/javax/crypto/Cipher.html">Cipher</a></code> class.</p>
|
|
||||||
|
|
||||||
<p>Use a secure random number generator (
|
|
||||||
<a href="{@docRoot}reference/java/security/SecureRandom.html">
|
|
||||||
<code>SecureRandom</code></a>) to initialize any cryptographic keys (<a
|
|
||||||
href="{@docRoot}reference/javax/crypto/KeyGenerator.html">
|
|
||||||
<code>KeyGenerator</code></a>). Use of a key that is not generated with a secure random
|
|
||||||
number generator significantly weakens the strength of the algorithm, and may
|
|
||||||
allow offline attacks.</p>
|
|
||||||
|
|
||||||
<p>If you need to store a key for repeated use, use a mechanism like
|
|
||||||
{@link java.security.KeyStore} that
|
|
||||||
provides a mechanism for long term storage and retrieval of cryptographic
|
|
||||||
keys.</p>
|
|
||||||
|
|
||||||
<h2>Conclusion</h2>
|
|
||||||
|
|
||||||
<p>Android provides developers with the ability to design applications with a
|
|
||||||
broad range of security requirements. These best practices will help you make
|
|
||||||
sure that your application takes advantage of the security benefits provided by
|
|
||||||
the platform.</p>
|
|
||||||
|
|
||||||
<p>You can receive more information on these topics and discuss security best
|
|
||||||
practices with other developers in the <a
|
|
||||||
href="http://groups.google.com/group/android-security-discuss">Android Security
|
|
||||||
Discuss</a> Google Group</p>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 16 KiB |
8
docs/html/training/best-performance.jd
Normal file
8
docs/html/training/best-performance.jd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
page.title=Best Practices for Performance
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes and articles help you build an app that's smooth, responsive,
|
||||||
|
and uses as little battery as possible.</p>
|
||||||
9
docs/html/training/best-security.jd
Normal file
9
docs/html/training/best-security.jd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
page.title=Best Practices for Security & Privacy
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes and articles provide information about how to
|
||||||
|
keep your app's data secure.</p>
|
||||||
12
docs/html/training/best-ux.jd
Normal file
12
docs/html/training/best-ux.jd
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
page.title=Best Practices for User Experience & UI
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes focus on the best Android user experience for your app.
|
||||||
|
In some cases, the success of your app on Android is heavily
|
||||||
|
affected by whether your app conforms to the user's expectations for
|
||||||
|
UI and navigation on an Android device. Follow these recommendations to ensure that
|
||||||
|
your app looks and behaves in a way that satisfies Android users.</p>
|
||||||
10
docs/html/training/building-connectivity.jd
Normal file
10
docs/html/training/building-connectivity.jd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
page.title=Building Apps with Connectivity & the Cloud
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes teach you how to connect your app to the world beyond the user's device.
|
||||||
|
You'll learn how to connect to other devices in the area, connect to the Internet, backup and
|
||||||
|
sync your app's data, and more.</p>
|
||||||
11
docs/html/training/building-graphics.jd
Normal file
11
docs/html/training/building-graphics.jd
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
page.title=Building Apps with Graphics & Animation
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes teach you how to accomplish tasks with graphics
|
||||||
|
that can give your app an edge on the competition.
|
||||||
|
If you want to go beyond the basic user interface to create a beautiful visual experience,
|
||||||
|
these classes will help you get there.</p>
|
||||||
9
docs/html/training/building-multimedia.jd
Normal file
9
docs/html/training/building-multimedia.jd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
page.title=Building Apps with Multimedia
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes teach you how to
|
||||||
|
create rich multimedia apps that behave the way users expect.</p>
|
||||||
9
docs/html/training/building-userinfo.jd
Normal file
9
docs/html/training/building-userinfo.jd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
page.title=Building Apps with User Info & Location
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes teach you how to add user personalization to your app. Some of the ways
|
||||||
|
you can do this is by identifying users, providing
|
||||||
|
information that's relevant to them, and providing information about the world around them.</p>
|
||||||
9
docs/html/training/distribute.jd
Normal file
9
docs/html/training/distribute.jd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
page.title=Using Google Play to Distribute & Monetize
|
||||||
|
page.trainingcourse=true
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>These classes focus on the business aspects of your app strategy, including techniques
|
||||||
|
for distributing your app on Google Play and techniques for building revenue.</p>
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
page.title=Android Training
|
page.title=Getting Started
|
||||||
|
page.trainingcourse=true
|
||||||
page.metaDescription=Android Training provides a collection of classes that aim to help you build great apps for Android. Each class explains the steps required to solve a problem or implement a feature using code snippets and sample code for you to use in your apps.
|
page.metaDescription=Android Training provides a collection of classes that aim to help you build great apps for Android. Each class explains the steps required to solve a problem or implement a feature using code snippets and sample code for you to use in your apps.
|
||||||
|
|
||||||
@jd:body
|
@jd:body
|
||||||
|
|
||||||
<p>Welcome to Android Training. Here you'll find a collection of classes that aim to help you
|
|
||||||
build great apps for Android, using best practices in a variety of framework topics.</p>
|
|
||||||
|
|
||||||
<p>Each class explains the steps required to solve a problem or implement a feature using code
|
<p>Welcome to Training. Each class provides a series of lessons that
|
||||||
snippets and sample code for you to use in your apps.</p>
|
describe how to accomplish a specific task with code samples you can re-use in your app.
|
||||||
|
Classes are organized into several groups you can see at the top-level of the left navigation.</p>
|
||||||
|
|
||||||
<p>This first section is focused on teaching you the bare essentials. If you're a new developer
|
<p>This first group, <em>Getting Started</em>, teaches you the bare
|
||||||
on Android, you should walk through each of these classes, beginning with
|
essentials for Android app development.
|
||||||
<a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>.</p></a>
|
If you're a new Android app developer, you should complete each of these classes in order:</p>
|
||||||
196
docs/html/training/perf-anr.jd
Normal file
196
docs/html/training/perf-anr.jd
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
page.title=Keeping Your App Responsive
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
<div id="tb-wrapper">
|
||||||
|
<div id="tb">
|
||||||
|
|
||||||
|
<h2>In this document</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a href="#anr">What Triggers ANR?</a></li>
|
||||||
|
<li><a href="#Avoiding">How to Avoid ANRs</a></li>
|
||||||
|
<li><a href="#Reinforcing">Reinforcing Responsiveness</a></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="figure" style="width:280px">
|
||||||
|
<img src="{@docRoot}images/anr.png" alt=""/>
|
||||||
|
<p class="img-caption"><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 feels sluggish, hang or freeze for significant periods, or take too
|
||||||
|
long to process input. The worst thing that can happen to your app's responsiveness
|
||||||
|
is an "Application Not Responding" (ANR) dialog.</p>
|
||||||
|
|
||||||
|
<p>In Android, the system guards against applications that are insufficiently
|
||||||
|
responsive for a period of time by displaying a dialog that says your app has
|
||||||
|
stopped responding, such as the dialog
|
||||||
|
in Figure 1. At this point, your app has been unresponsive for a considerable
|
||||||
|
period of time so the system offers the user an option to quit the app. It's critical
|
||||||
|
to design responsiveness into your application so the system never displays
|
||||||
|
an ANR dialog to the user. </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>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) on the UI thread so the system can't
|
||||||
|
process incoming user input events. Or perhaps the app
|
||||||
|
spends too much time building an elaborate in-memory
|
||||||
|
structure or computing the next move in a game on the UI thread. It's always important to make
|
||||||
|
sure these computations are efficient, but even the
|
||||||
|
most efficient code still takes time to run.</p>
|
||||||
|
|
||||||
|
<p>In any situation in which your app performs a potentially lengthy operation,
|
||||||
|
<strong>you should not perform the work on the UI thread</strong>, but instead create a
|
||||||
|
worker thread and do most of the work there. This keeps the UI thread (which drives the user
|
||||||
|
interface event loop) running and prevents the system from concluding that your code
|
||||||
|
has frozen. Because such threading usually is accomplished at the class
|
||||||
|
level, you can think of responsiveness as a <em>class</em> problem. (Compare
|
||||||
|
this with basic code performance, which is a <em>method</em>-level
|
||||||
|
concern.)</p>
|
||||||
|
|
||||||
|
<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 (such as key press or screen touch events)
|
||||||
|
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 ANRs</h2>
|
||||||
|
|
||||||
|
<p>Android applications normally run entirely on a single thread by default
|
||||||
|
the "UI thread" or "main thread").
|
||||||
|
This means anything your application is doing in the UI 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
|
||||||
|
broadcasts.</p>
|
||||||
|
|
||||||
|
<p>Therefore, any method that runs in the UI thread should do as little work
|
||||||
|
as possible on that thread. In particular, activities should do as little as possible to set
|
||||||
|
up in key life-cycle methods such as {@link android.app.Activity#onCreate onCreate()}
|
||||||
|
and {@link android.app.Activity#onResume onResume()}.
|
||||||
|
Potentially long running operations such as network
|
||||||
|
or database operations, or computationally expensive calculations such as
|
||||||
|
resizing bitmaps should be done in a worker thread (or in the case of databases
|
||||||
|
operations, via an asynchronous request).</p>
|
||||||
|
|
||||||
|
<p>The most effecive way to create a worker thread for longer
|
||||||
|
operations is with the {@link android.os.AsyncTask}
|
||||||
|
class. Simply extend {@link android.os.AsyncTask} and implement the
|
||||||
|
{@link android.os.AsyncTask#doInBackground doInBackground()} method to perform the work.
|
||||||
|
To post progress changes to the user, you can call
|
||||||
|
{@link android.os.AsyncTask#publishProgress publishProgress()}, which invokes the
|
||||||
|
{@link android.os.AsyncTask#onProgressUpdate onProgressUpdate()} callback method. From your
|
||||||
|
implementation of {@link android.os.AsyncTask#onProgressUpdate onProgressUpdate()} (which
|
||||||
|
runs on the UI thread), you can notify the user. For example:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
|
||||||
|
// Do the long-running work in here
|
||||||
|
protected Long doInBackground(URL... urls) {
|
||||||
|
int count = urls.length;
|
||||||
|
long totalSize = 0;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
totalSize += Downloader.downloadFile(urls[i]);
|
||||||
|
publishProgress((int) ((i / (float) count) * 100));
|
||||||
|
// Escape early if cancel() is called
|
||||||
|
if (isCancelled()) break;
|
||||||
|
}
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is called each time you call publishProgress()
|
||||||
|
protected void onProgressUpdate(Integer... progress) {
|
||||||
|
setProgressPercent(progress[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is called when doInBackground() is finished
|
||||||
|
protected void onPostExecute(Long result) {
|
||||||
|
showNotification("Downloaded " + result + " bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>To execute this worker thread, simply create an instance and
|
||||||
|
call {@link android.os.AsyncTask#execute execute()}:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
new DownloadFilesTask().execute(url1, url2, url3);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Although it's more complicated than {@link android.os.AsyncTask}, you might want to instead
|
||||||
|
create your own {@link java.lang.Thread} or {@link android.os.HandlerThread} class. If you do,
|
||||||
|
you should set the thread priority to "background" priority by calling {@link
|
||||||
|
android.os.Process#setThreadPriority Process.setThreadPriority()} and passing {@link
|
||||||
|
android.os.Process#THREAD_PRIORITY_BACKGROUND}. If you don't set the thread to a lower priority
|
||||||
|
this way, then the thread could still slow down your app because it operates at the same priority
|
||||||
|
as the UI thread by default.</p>
|
||||||
|
|
||||||
|
<p>If you implement {@link java.lang.Thread} or {@link android.os.HandlerThread},
|
||||||
|
be sure that your UI thread does not block while waiting for the worker thread to
|
||||||
|
complete—do not call {@link java.lang.Thread#wait Thread.wait()} or
|
||||||
|
{@link java.lang.Thread#sleep Thread.sleep()}. Instead of blocking while waiting for a worker
|
||||||
|
thread to complete, your main thread should provide a {@link
|
||||||
|
android.os.Handler} for the other threads to post back to upon completion.
|
||||||
|
Designing your application in this way will allow your app's UI thread to remain
|
||||||
|
responsive to input and thus avoid ANR dialogs caused by the 5 second input
|
||||||
|
event timeout.</p>
|
||||||
|
|
||||||
|
<p>The specific constraint on {@link android.content.BroadcastReceiver} execution time
|
||||||
|
emphasizes what broadcast receivers are meant to do:
|
||||||
|
small, discrete amounts of work in the background such
|
||||||
|
as saving a setting or registering a {@link android.app.Notification}. So as with other methods
|
||||||
|
called in the UI thread, applications should avoid potentially long-running
|
||||||
|
operations or calculations in a broadcast receiver. But instead of doing intensive
|
||||||
|
tasks via worker threads, your
|
||||||
|
application should start an {@link android.app.IntentService} if a
|
||||||
|
potentially long running action needs to be taken in response to an intent
|
||||||
|
broadcast.</p>
|
||||||
|
|
||||||
|
<p class="note"><strong>Tip:</strong>
|
||||||
|
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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Reinforcing">Reinforce Responsiveness</h2>
|
||||||
|
|
||||||
|
<p>Generally, 100 to 200ms is the threshold beyond which users will perceive
|
||||||
|
slowness in an application. As such, here
|
||||||
|
are some additional tips beyond what you should do to avoid ANR and
|
||||||
|
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 (such as with a {@link
|
||||||
|
android.widget.ProgressBar} in your UI).</li>
|
||||||
|
|
||||||
|
<li>For games specifically, do calculations for moves in a worker
|
||||||
|
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, indicate that
|
||||||
|
loading is in progress and fill 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>
|
||||||
|
|
||||||
|
<li>Use performance tools such as <a href="{@docRoot}tools/help/systrace.html">Systrace</a>
|
||||||
|
and <a href="{@docRoot}tools/help/traceview.html">Traceview</a> to determine bottlenecks
|
||||||
|
in your app's responsiveness.</li>
|
||||||
|
</ul>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
page.title=JNI Tips
|
page.title=JNI Tips
|
||||||
@jd:body
|
@jd:body
|
||||||
|
|
||||||
<div id="qv-wrapper">
|
<div id="tb-wrapper">
|
||||||
<div id="qv">
|
<div id="tb">
|
||||||
|
|
||||||
<h2>In this document</h2>
|
<h2>In this document</h2>
|
||||||
<ol>
|
<ol>
|
||||||
@@ -1,21 +1,20 @@
|
|||||||
page.title=Designing for Performance
|
page.title=Performance Tips
|
||||||
@jd:body
|
@jd:body
|
||||||
|
|
||||||
<div id="qv-wrapper">
|
<div id="tb-wrapper">
|
||||||
<div id="qv">
|
<div id="tb">
|
||||||
|
|
||||||
<h2>In this document</h2>
|
<h2>In this document</h2>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="#intro">Introduction</a></li>
|
<li><a href="#ObjectCreation">Avoid Creating Unnecessary Objects</a></li>
|
||||||
<li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
|
<li><a href="#PreferStatic">Prefer Static Over Virtual</a></li>
|
||||||
<li><a href="#object_creation">Avoid Creating Unnecessary Objects</a></li>
|
<li><a href="#UseFinal">Use Static Final For Constants</a></li>
|
||||||
<li><a href="#myths">Performance Myths</a></li>
|
<li><a href="#GettersSetters">Avoid Internal Getters/Setters</a></li>
|
||||||
<li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
|
<li><a href="#Loops">Use Enhanced For Loop Syntax</a></li>
|
||||||
<li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
|
<li><a href="#PackageInner">Consider Package Instead of Private Access with Private Inner Classes</a></li>
|
||||||
<li><a href="#use_final">Use Static Final For Constants</a></li>
|
<li><a href="#AvoidFloat">Avoid Using Floating-Point</a></li>
|
||||||
<li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
|
<li><a href="#UseLibraries">Know and Use the Libraries</a></li>
|
||||||
<li><a href="#package_inner">Consider Package Instead of Private Access with Inner Classes</a></li>
|
<li><a href="#NativeMethods">Use Native Methods Carefully</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="#library">Know And Use The Libraries</a></li>
|
||||||
<li><a href="#native_methods">Use Native Methods Judiciously</a></li>
|
<li><a href="#native_methods">Use Native Methods Judiciously</a></li>
|
||||||
<li><a href="#closing_notes">Closing Notes</a></li>
|
<li><a href="#closing_notes">Closing Notes</a></li>
|
||||||
@@ -24,20 +23,12 @@ page.title=Designing for Performance
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>An Android application will run on a mobile device with limited computing
|
<p>This document primarily covers micro-optimizations that can improve overall app performance
|
||||||
power and storage, and constrained battery life. Because of
|
when combined, but it's unlikely that these changes will result in dramatic
|
||||||
this, it should be <em>efficient</em>. Battery life is one reason you might
|
performance effects. Choosing the right algorithms and data structures should always be your
|
||||||
want to optimize your app even if it already seems to run "fast enough".
|
priority, but is outside the scope of this document. You should use the tips in this document
|
||||||
Battery life is important to users, and Android's battery usage breakdown
|
as general coding practices that you can incorporate into your habits for general code
|
||||||
means users will know if your app is responsible draining their battery.</p>
|
efficiency.</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>
|
<p>There are two basic rules for writing efficient code:</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -45,52 +36,31 @@ outside the scope of this document.</p>
|
|||||||
<li>Don't allocate memory if you can avoid it.</li>
|
<li>Don't allocate memory if you can avoid it.</li>
|
||||||
</ul>
|
</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
|
<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
|
app is that your app is certain to be running on multiple types of
|
||||||
hardware platforms. Different versions of the VM running on different
|
hardware. Different versions of the VM running on different
|
||||||
processors running at different speeds. It's not even generally the case
|
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",
|
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
|
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
|
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"
|
are also huge differences between devices with and without a
|
||||||
|
<acronym title="Just In Time compiler">JIT</acronym>: the best
|
||||||
code for a device with a JIT is not always the best code for a device
|
code for a device with a JIT is not always the best code for a device
|
||||||
without.</p>
|
without.</p>
|
||||||
|
|
||||||
<p>If you want to know how your app performs on a given device, you need to
|
<p>To ensure your app performs well across a wide variety of devices, ensure
|
||||||
test on that device.</p>
|
your code is efficient at all levels and agressively optimize your performance.</p>
|
||||||
|
|
||||||
<a name="object_creation"></a>
|
|
||||||
<h2>Avoid Creating Unnecessary Objects</h2>
|
|
||||||
|
|
||||||
<p>Object creation is never free. A generational GC with per-thread allocation
|
<h2 id="ObjectCreation">Avoid Creating Unnecessary Objects</h2>
|
||||||
|
|
||||||
|
<p>Object creation is never free. A generational garbage collector with per-thread allocation
|
||||||
pools for temporary objects can make allocation cheaper, but allocating memory
|
pools for temporary objects can make allocation cheaper, but allocating memory
|
||||||
is always more expensive than not allocating memory.</p>
|
is always more expensive than not allocating memory.</p>
|
||||||
|
|
||||||
<p>If you allocate objects in a user interface loop, you will force a periodic
|
<p>As you allocate more objects in your app, you will force a periodic
|
||||||
garbage collection, creating little "hiccups" in the user experience. The
|
garbage collection, creating little "hiccups" in the user experience. The
|
||||||
concurrent collector introduced in Gingerbread helps, but unnecessary work
|
concurrent garbage collector introduced in Android 2.3 helps, but unnecessary work
|
||||||
should always be avoided.</p>
|
should always be avoided.</p>
|
||||||
|
|
||||||
<p>Thus, you should avoid creating object instances you don't need to. Some
|
<p>Thus, you should avoid creating object instances you don't need to. Some
|
||||||
@@ -98,12 +68,12 @@ examples of things that can help:</p>
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>If you have a method returning a string, and you know that its result
|
<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
|
will always be appended to a {@link java.lang.StringBuffer} anyway, change your signature
|
||||||
and implementation so that the function does the append directly,
|
and implementation so that the function does the append directly,
|
||||||
instead of creating a short-lived temporary object.</li>
|
instead of creating a short-lived temporary object.</li>
|
||||||
<li>When extracting strings from a set of input data, try
|
<li>When extracting strings from a set of input data, try
|
||||||
to return a substring of the original data, instead of creating a copy.
|
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[]
|
You will create a new {@link java.lang.String} object, but it will share the {@code char[]}
|
||||||
with the data. (The trade-off being that if you're only using a small
|
with the data. (The trade-off being that if you're only using a small
|
||||||
part of the original input, you'll be keeping it all around in memory
|
part of the original input, you'll be keeping it all around in memory
|
||||||
anyway if you go this route.)</li>
|
anyway if you go this route.)</li>
|
||||||
@@ -113,16 +83,18 @@ examples of things that can help:</p>
|
|||||||
parallel single one-dimension arrays:</p>
|
parallel single one-dimension arrays:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>An array of ints is a much better than an array of Integers,
|
<li>An array of {@code int}s is a much better than an array of {@link java.lang.Integer}
|
||||||
|
objects,
|
||||||
but this also generalizes to the fact that two parallel arrays of ints
|
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)
|
are also a <strong>lot</strong> more efficient than an array of {@code (int,int)}
|
||||||
objects. The same goes for any combination of primitive types.</li>
|
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
|
<li>If you need to implement a container that stores tuples of {@code (Foo,Bar)}
|
||||||
generally much better than a single array of custom (Foo,Bar) objects.
|
objects, try to remember that two parallel {@code Foo[]} and {@code Bar[]} arrays are
|
||||||
|
generally much better than a single array of custom {@code (Foo,Bar)} objects.
|
||||||
(The exception to this, of course, is when you're designing an API for
|
(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
|
other code to access. In those cases, it's usually better to make a small
|
||||||
good API design for a small hit in speed. But in your own internal
|
compromise to the speed in order to achieve a good API design. But in your own internal
|
||||||
code, you should try and be as efficient as possible.)</li>
|
code, you should try and be as efficient as possible.)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -130,66 +102,28 @@ parallel single one-dimension arrays:</p>
|
|||||||
can. Fewer objects created mean less-frequent garbage collection, which has
|
can. Fewer objects created mean less-frequent garbage collection, which has
|
||||||
a direct impact on user experience.</p>
|
a direct impact on user experience.</p>
|
||||||
|
|
||||||
<a name="avoid_enums" id="avoid_enums"></a>
|
|
||||||
<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
|
<h2 id="PreferStatic">Prefer Static Over Virtual</h2>
|
||||||
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.
|
<p>If you don't need to access an object's fields, make your method static.
|
||||||
Invocations will be about 15%-20% faster.
|
Invocations will be about 15%-20% faster.
|
||||||
It's also good practice, because you can tell from the method
|
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>
|
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>
|
|
||||||
|
|
||||||
<p>Note that if you're using ProGuard, you can have the best
|
<h2 id="UseFinal">Use Static Final For Constants</h2>
|
||||||
of both worlds because ProGuard can inline accessors for you.</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>
|
<p>Consider the following declaration at the top of a class:</p>
|
||||||
|
|
||||||
<pre>static int intVal = 42;
|
<pre>
|
||||||
static String strVal = "Hello, world!";</pre>
|
static int intVal = 42;
|
||||||
|
static String strVal = "Hello, world!";
|
||||||
|
</pre>
|
||||||
|
|
||||||
<p>The compiler generates a class initializer method, called
|
<p>The compiler generates a class initializer method, called
|
||||||
<code><clinit></code>, that is executed when the class is first used.
|
<code><clinit></code>, that is executed when the class is first used.
|
||||||
@@ -200,84 +134,125 @@ lookups.</p>
|
|||||||
|
|
||||||
<p>We can improve matters with the "final" keyword:</p>
|
<p>We can improve matters with the "final" keyword:</p>
|
||||||
|
|
||||||
<pre>static final int intVal = 42;
|
<pre>
|
||||||
static final String strVal = "Hello, world!";</pre>
|
static final int intVal = 42;
|
||||||
|
static final String strVal = "Hello, world!";
|
||||||
|
</pre>
|
||||||
|
|
||||||
<p>The class no longer requires a <code><clinit></code> method,
|
<p>The class no longer requires a <code><clinit></code> method,
|
||||||
because the constants go into static field initializers in the dex file.
|
because the constants go into static field initializers in the dex file.
|
||||||
Code that refers to <code>intVal</code> will use
|
Code that refers to <code>intVal</code> will use
|
||||||
the integer value 42 directly, and accesses to <code>strVal</code> will
|
the integer value 42 directly, and accesses to <code>strVal</code> will
|
||||||
use a relatively inexpensive "string constant" instruction instead of a
|
use a relatively inexpensive "string constant" instruction instead of a
|
||||||
field lookup. (Note that this optimization only applies to primitive types and
|
field lookup.</p>
|
||||||
<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>
|
<p class="note"><strong>Note:</strong> This optimization applies only to primitive types and
|
||||||
<h2>Use Enhanced For Loop Syntax</h2>
|
{@link java.lang.String} constants, not arbitrary reference types. Still, it's good
|
||||||
|
practice to declare constants <code>static final</code> whenever possible.</p>
|
||||||
|
|
||||||
<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.
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="GettersSetters">Avoid Internal Getters/Setters</h2>
|
||||||
|
|
||||||
|
<p>In native languages like C++ it's common practice to use getters
|
||||||
|
(<code>i = getCount()</code>) instead of accessing the field directly (<code>i
|
||||||
|
= mCount</code>). This is an excellent habit for C++ and is often practiced in other
|
||||||
|
object oriented languages like C# and Java, 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>However, this is a bad idea on Android. 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 <acronym title="Just In Time compiler">JIT</acronym>,
|
||||||
|
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.</p>
|
||||||
|
|
||||||
|
<p>Note that if you're using <a href="{@docRoot}tools/help/proguard.html">ProGuard</a>,
|
||||||
|
you can have the best of both worlds because ProGuard can inline accessors for you.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Loops">Use Enhanced For Loop Syntax</h2>
|
||||||
|
|
||||||
|
<p>The enhanced <code>for</code> loop (also sometimes known as "for-each" loop) can be used
|
||||||
|
for collections that implement the {@link java.lang.Iterable} interface and for arrays.
|
||||||
With collections, an iterator is allocated to make interface calls
|
With collections, an iterator is allocated to make interface calls
|
||||||
to hasNext() and next(). With an ArrayList, a hand-written counted loop is
|
to {@code hasNext()} and {@code next()}. With an {@link java.util.ArrayList},
|
||||||
|
a hand-written counted loop is
|
||||||
about 3x faster (with or without JIT), but for other collections the enhanced
|
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>
|
for loop syntax will be exactly equivalent to explicit iterator usage.</p>
|
||||||
|
|
||||||
<p>There are several alternatives for iterating through an array:</p>
|
<p>There are several alternatives for iterating through an array:</p>
|
||||||
|
|
||||||
<pre> static class Foo {
|
<pre>
|
||||||
int mSplat;
|
static class Foo {
|
||||||
}
|
int mSplat;
|
||||||
Foo[] mArray = ...
|
}
|
||||||
|
|
||||||
public void zero() {
|
Foo[] mArray = ...
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < mArray.length; ++i) {
|
|
||||||
sum += mArray[i].mSplat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void one() {
|
public void zero() {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
Foo[] localArray = mArray;
|
for (int i = 0; i < mArray.length; ++i) {
|
||||||
int len = localArray.length;
|
sum += mArray[i].mSplat;
|
||||||
|
|
||||||
for (int i = 0; i < len; ++i) {
|
|
||||||
sum += localArray[i].mSplat;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void two() {
|
public void one() {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (Foo a : mArray) {
|
Foo[] localArray = mArray;
|
||||||
sum += a.mSplat;
|
int len = localArray.length;
|
||||||
}
|
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
sum += localArray[i].mSplat;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void two() {
|
||||||
|
int sum = 0;
|
||||||
|
for (Foo a : mArray) {
|
||||||
|
sum += a.mSplat;
|
||||||
|
}
|
||||||
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p><strong>zero()</strong> is slowest, because the JIT can't yet optimize away
|
<p><code>zero()</code> is slowest, because the JIT can't yet optimize away
|
||||||
the cost of getting the array length once for every iteration through the
|
the cost of getting the array length once for every iteration through the
|
||||||
loop.</p>
|
loop.</p>
|
||||||
|
|
||||||
<p><strong>one()</strong> is faster. It pulls everything out into local
|
<p><code>one()</code> is faster. It pulls everything out into local
|
||||||
variables, avoiding the lookups. Only the array length offers a performance
|
variables, avoiding the lookups. Only the array length offers a performance
|
||||||
benefit.</p>
|
benefit.</p>
|
||||||
|
|
||||||
<p><strong>two()</strong> is fastest for devices without a JIT, and
|
<p><code>two()</code> is fastest for devices without a JIT, and
|
||||||
indistinguishable from <strong>one()</strong> for devices with a JIT.
|
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
|
It uses the enhanced for loop syntax introduced in version 1.5 of the Java
|
||||||
programming language.</p>
|
programming language.</p>
|
||||||
|
|
||||||
<p>To summarize: use the enhanced for loop by default, but consider a
|
<p>So, you should use the enhanced <code>for</code> loop by default, but consider a
|
||||||
hand-written counted loop for performance-critical ArrayList iteration.</p>
|
hand-written counted loop for performance-critical {@link java.util.ArrayList} iteration.</p>
|
||||||
|
|
||||||
<p>(See also <em>Effective Java</em> item 46.)</p>
|
<p class="note"><strong>Tip:</strong>
|
||||||
|
Also see Josh Bloch's <em>Effective Java</em>, item 46.</p>
|
||||||
|
|
||||||
<a name="package_inner" id="package_inner"></a>
|
|
||||||
<h2>Consider Package Instead of Private Access with Private Inner Classes</h2>
|
|
||||||
|
<h2 id="PackageInner">Consider Package Instead of Private Access with Private Inner Classes</h2>
|
||||||
|
|
||||||
<p>Consider the following class definition:</p>
|
<p>Consider the following class definition:</p>
|
||||||
|
|
||||||
<pre>public class Foo {
|
<pre>
|
||||||
|
public class Foo {
|
||||||
private class Inner {
|
private class Inner {
|
||||||
void stuff() {
|
void stuff() {
|
||||||
Foo.this.doStuff(Foo.this.mValue);
|
Foo.this.doStuff(Foo.this.mValue);
|
||||||
@@ -297,7 +272,7 @@ hand-written counted loop for performance-critical ArrayList iteration.</p>
|
|||||||
}
|
}
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>The key things to note here are that we define a private inner class
|
<p>What's important here is that we define a private inner class
|
||||||
(<code>Foo$Inner</code>) that directly accesses a private method and a private
|
(<code>Foo$Inner</code>) that directly accesses a private method and a private
|
||||||
instance field in the outer class. This is legal, and the code prints "Value is
|
instance field in the outer class. This is legal, and the code prints "Value is
|
||||||
27" as expected.</p>
|
27" as expected.</p>
|
||||||
@@ -309,7 +284,8 @@ 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
|
members. To bridge the gap, the compiler generates a couple of synthetic
|
||||||
methods:</p>
|
methods:</p>
|
||||||
|
|
||||||
<pre>/*package*/ static int Foo.access$100(Foo foo) {
|
<pre>
|
||||||
|
/*package*/ static int Foo.access$100(Foo foo) {
|
||||||
return foo.mValue;
|
return foo.mValue;
|
||||||
}
|
}
|
||||||
/*package*/ static void Foo.access$200(Foo foo, int value) {
|
/*package*/ static void Foo.access$200(Foo foo, int value) {
|
||||||
@@ -317,7 +293,7 @@ methods:</p>
|
|||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>The inner class code calls these static methods whenever it needs to
|
<p>The inner class code calls these static methods whenever it needs to
|
||||||
access the <code>mValue</code> field or invoke the <code>doStuff</code> method
|
access the <code>mValue</code> field or invoke the <code>doStuff()</code> method
|
||||||
in the outer class. What this means is that the code above really boils down to
|
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.
|
a case where you're accessing member fields through accessor methods.
|
||||||
Earlier we talked about how accessors are slower than direct field
|
Earlier we talked about how accessors are slower than direct field
|
||||||
@@ -330,41 +306,52 @@ package access, rather than private access. Unfortunately this means the fields
|
|||||||
can be accessed directly by other classes in the same package, so you shouldn't
|
can be accessed directly by other classes in the same package, so you shouldn't
|
||||||
use this in public API.</p>
|
use this in public API.</p>
|
||||||
|
|
||||||
<a name="avoidfloat" id="avoidfloat"></a>
|
|
||||||
<h2>Use Floating-Point Judiciously</h2>
|
|
||||||
|
|
||||||
|
<h2 id="AvoidFloat">Avoid Using Floating-Point</h2>
|
||||||
|
|
||||||
<p>As a rule of thumb, floating-point is about 2x slower than integer on
|
<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
|
Android-powered devices.</p>
|
||||||
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
|
<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>
|
<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
|
is 2x larger. As with desktop machines, assuming space isn't an issue, you
|
||||||
should prefer <code>double</code> to <code>float</code>.</p>
|
should prefer <code>double</code> to <code>float</code>.</p>
|
||||||
|
|
||||||
<p>Also, even for integers, some chips have hardware multiply but lack
|
<p>Also, even for integers, some processors have hardware multiply but lack
|
||||||
hardware divide. In such cases, integer division and modulus operations are
|
hardware divide. In such cases, integer division and modulus operations are
|
||||||
performed in software — something to think about if you're designing a
|
performed in software—something to think about if you're designing a
|
||||||
hash table or doing lots of math.</p>
|
hash table or doing lots of math.</p>
|
||||||
|
|
||||||
<a name="library" id="library"></a>
|
|
||||||
<h2>Know And Use The Libraries</h2>
|
|
||||||
|
|
||||||
|
<h2 id="UseLibraries">Know and Use the Libraries</h2>
|
||||||
|
|
||||||
<p>In addition to all the usual reasons to prefer library code over rolling
|
<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
|
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
|
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
|
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
|
here is {@link java.lang.String#indexOf String.indexOf()} and
|
||||||
an inlined intrinsic. Similarly, the <code>System.arraycopy</code> method
|
related APIs, which Dalvik replaces with
|
||||||
|
an inlined intrinsic. Similarly, the {@link java.lang.System#arraycopy
|
||||||
|
System.arraycopy()} method
|
||||||
is about 9x faster than a hand-coded loop on a Nexus One with the JIT.</p>
|
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>
|
<p class="note"><strong>Tip:</strong>
|
||||||
<h2>Use Native Methods Judiciously</h2>
|
Also see Josh Bloch's <em>Effective Java</em>, item 47.</p>
|
||||||
|
|
||||||
<p>Native code isn't necessarily more efficient than Java. For one thing,
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="NativeMethods">Use Native Methods Carefully</h2>
|
||||||
|
|
||||||
|
<p>Developing your app with native code using the
|
||||||
|
<a href="{@docRoot}tools/sdk/ndk/index.html">Android NDK</a>
|
||||||
|
isn't necessarily more efficient than programming with the
|
||||||
|
Java language. For one thing,
|
||||||
there's a cost associated with the Java-native transition, and the JIT can't
|
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
|
optimize across these boundaries. If you're allocating native resources (memory
|
||||||
on the native heap, file descriptors, or whatever), it can be significantly
|
on the native heap, file descriptors, or whatever), it can be significantly
|
||||||
@@ -376,22 +363,48 @@ 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>
|
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
|
<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>
|
that you want to port to Android, not for "speeding up" parts of your Android app
|
||||||
|
written with the Java language.</p>
|
||||||
|
|
||||||
<p>If you do need to use native code, you should read our
|
<p>If you do need to use native code, you should read our
|
||||||
<a href="{@docRoot}guide/practices/jni.html">JNI Tips</a>.</p>
|
<a href="{@docRoot}guide/practices/jni.html">JNI Tips</a>.</p>
|
||||||
|
|
||||||
<p>(See also <em>Effective Java</em> item 54.)</p>
|
<p class="note"><strong>Tip:</strong>
|
||||||
|
Also see Josh Bloch's <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,
|
|
||||||
|
|
||||||
|
<h2 id="Myths">Performance Myths</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<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.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Measure">Always Measure</h2>
|
||||||
|
|
||||||
|
<p>Before you start optimizing, make sure you have a problem that you
|
||||||
|
need to solve. 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>
|
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
|
<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>
|
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
|
<p>The benchmarks are built with the
|
||||||
<a href="http://code.google.com/p/caliper/">Caliper</a> microbenchmarking
|
<a href="http://code.google.com/p/caliper/">Caliper</a> microbenchmarking
|
||||||
@@ -407,4 +420,14 @@ 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
|
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
|
back. It's especially important after making changes suggested by Traceview
|
||||||
data to ensure that the resulting code actually runs faster when run without
|
data to ensure that the resulting code actually runs faster when run without
|
||||||
Traceview.
|
Traceview.</p>
|
||||||
|
|
||||||
|
<p>For more help profiling and debugging your apps, see the following documents:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="{@docRoot}tools/debugging/debugging-tracing.html">Profiling with
|
||||||
|
Traceview and dmtracedump</a></li>
|
||||||
|
<li><a href="{@docRoot}tools/debugging/systrace.html">Analysing Display and Performance
|
||||||
|
with Systrace</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
759
docs/html/training/security-tips.jd
Normal file
759
docs/html/training/security-tips.jd
Normal file
@@ -0,0 +1,759 @@
|
|||||||
|
page.title=Security Tips
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
<div id="tb-wrapper">
|
||||||
|
<div id="tb">
|
||||||
|
<h2>In this document</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a href="#StoringData">Storing Data</a></li>
|
||||||
|
<li><a href="#Permissions">Using Permissions</a></li>
|
||||||
|
<li><a href="#Networking">Using Networking</a></li>
|
||||||
|
<li><a href="#InputValidation">Performing Input Validation</a></li>
|
||||||
|
<li><a href="#UserData">Handling User Data</a></li>
|
||||||
|
<li><a href="#WebView">Using WebView</a></li>
|
||||||
|
<li><a href="#Crypto">Using Cryptography</a></li>
|
||||||
|
<li><a href="#IPC">Using Interprocess Communication</a></li>
|
||||||
|
<li><a href="#DynamicCode">Dynamically Loading Code</a></li>
|
||||||
|
<li><a href="#Dalvik">Security in a Virtual Machine</a></li>
|
||||||
|
<li><a href="#Native">Security in Native Code</a></li>
|
||||||
|
</ol>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a href="http://source.android.com/tech/security/index.html">Android
|
||||||
|
Security Overview</a></li>
|
||||||
|
<li><a href="{@docRoot}guide/topics/security/permissions.html">Permissions</a></li>
|
||||||
|
</ol>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Android has security features built
|
||||||
|
into the operating system that significantly reduce the frequency and impact of
|
||||||
|
application security issues. The system is designed so you can typically build your apps with
|
||||||
|
default system and file permissions and avoid difficult decisions about security.</p>
|
||||||
|
|
||||||
|
<p>Some of the core security features that help you build secure apps
|
||||||
|
include:
|
||||||
|
<ul>
|
||||||
|
<li>The Android Application Sandbox, which isolates your app data and code execution
|
||||||
|
from other apps.</li>
|
||||||
|
<li>An application framework with robust implementations of common
|
||||||
|
security functionality such as cryptography, permissions, and secure
|
||||||
|
<acronym title="Interprocess Communication">IPC</acronym>.</li>
|
||||||
|
<li>Technologies like ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD
|
||||||
|
calloc, and Linux mmap_min_addr to mitigate risks associated with common memory
|
||||||
|
management errors.</li>
|
||||||
|
<li>An encrypted filesystem that can be enabled to protect data on lost or
|
||||||
|
stolen devices.</li>
|
||||||
|
<li>User-granted permissions to restrict access to system features and user data.</li>
|
||||||
|
<li>Application-defined permissions to control application data on a per-app basis.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Nevertheless, it is important that you be familiar with the Android
|
||||||
|
security best practices in this document. Following these practices as general coding habits
|
||||||
|
will reduce the likelihood of inadvertently introducing security issues that
|
||||||
|
adversely affect your users.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="StoringData">Storing Data</h2>
|
||||||
|
|
||||||
|
<p>The most common security concern for an application on Android is whether the data
|
||||||
|
that you save on the device is accessible to other apps. There are three fundamental
|
||||||
|
ways to save data on the device:</p>
|
||||||
|
|
||||||
|
<h3 id="InternalStorage">Using internal storage</h3>
|
||||||
|
|
||||||
|
<p>By default, files that you create on <a
|
||||||
|
href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal
|
||||||
|
storage</a> are accessible only to your app. This
|
||||||
|
protection is implemented by Android and is sufficient for most
|
||||||
|
applications.</p>
|
||||||
|
|
||||||
|
<p>You should generally avoid using the {@link android.content.Context#MODE_WORLD_WRITEABLE} or
|
||||||
|
{@link android.content.Context#MODE_WORLD_READABLE} modes for
|
||||||
|
<acronym title="Interprocess Communication">IPC</acronym> files because they do not provide
|
||||||
|
the ability to limit data access to particular applications, nor do they
|
||||||
|
provide any control on data format. If you want to share your data with other
|
||||||
|
app processes, you might instead consider using a
|
||||||
|
<a href="{@docRoot}guide/topics/providers/content-providers.html">content provider</a>, which
|
||||||
|
offers read and write permissions to other apps and can make
|
||||||
|
dynamic permission grants on a case-by-case basis.</p>
|
||||||
|
|
||||||
|
<p>To provide additional protection for sensitive data, you might
|
||||||
|
choose to encrypt local files using a key that is not directly accessible to the
|
||||||
|
application. For example, a key can be placed in a {@link java.security.KeyStore}
|
||||||
|
and protected with a user password that is not stored on the device. While this
|
||||||
|
does not protect data from a root compromise that can monitor the user
|
||||||
|
inputting the password, it can provide protection for a lost device without <a
|
||||||
|
href="http://source.android.com/tech/encryption/index.html">file system
|
||||||
|
encryption</a>.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="ExternalStorage">Using external storage</h3>
|
||||||
|
|
||||||
|
<p>Files created on <a
|
||||||
|
href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">external
|
||||||
|
storage</a>, such as SD Cards, are globally readable and writable. Because
|
||||||
|
external storage can be removed by the user and also modified by any
|
||||||
|
application, you should not store sensitive information using
|
||||||
|
external storage.</p>
|
||||||
|
|
||||||
|
<p>As with data from any untrusted source, you should <a href="#InputValidation">perform input
|
||||||
|
validation</a> when handling data from external storage.
|
||||||
|
We strongly recommend that you not store executables or
|
||||||
|
class files on external storage prior to dynamic loading. If your app
|
||||||
|
does retrieve executable files from external storage, the files should be signed and
|
||||||
|
cryptographically verified prior to dynamic loading.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="ContentProviders">Using content providers</h3>
|
||||||
|
|
||||||
|
<p><a href="{@docRoot}guide/topics/providers/content-providers.html">Content providers</a>
|
||||||
|
offer a structured storage mechanism that can be limited
|
||||||
|
to your own application or exported to allow access by other applications.
|
||||||
|
If you do not intend to provide other
|
||||||
|
applications with access to your {@link android.content.ContentProvider}, mark them as <code><a
|
||||||
|
href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
|
||||||
|
android:exported=false</a></code> in the application manifest. Otherwise, set the <code><a
|
||||||
|
href="{@docRoot}guide/topics/manifest/provider-element.html#exported">android:exported</a></code>
|
||||||
|
attribute {@code "true"} to allow other apps to access the stored data.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>When creating a {@link android.content.ContentProvider}
|
||||||
|
that will be exported for use by other applications, you can specify a single
|
||||||
|
<a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">permission
|
||||||
|
</a> for reading and writing, or distinct permissions for reading and writing
|
||||||
|
within the manifest. We recommend that you limit your permissions to those
|
||||||
|
required to accomplish the task at hand. Keep in mind that it’s usually
|
||||||
|
easier to add permissions later to expose new functionality than it is to take
|
||||||
|
them away and break existing users.</p>
|
||||||
|
|
||||||
|
<p>If you are using a content provider
|
||||||
|
for sharing data between only your own apps, it is preferable to use the
|
||||||
|
<a href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">{@code
|
||||||
|
android:protectionLevel}</a> attribute set to {@code "signature"} protection.
|
||||||
|
Signature permissions do not require user confirmation,
|
||||||
|
so they provide a better user experience and more controlled access to the
|
||||||
|
content provider data when the apps accessing the data are
|
||||||
|
<a href="{@docRoot}tools/publishing/app-signing.html">signed</a> with
|
||||||
|
the same key.</p>
|
||||||
|
|
||||||
|
<p>Content providers can also provide more granular access by declaring the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">{@code
|
||||||
|
android:grantUriPermissions}</a> attribute and using the {@link
|
||||||
|
android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} and {@link
|
||||||
|
android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} flags in the
|
||||||
|
{@link android.content.Intent} object
|
||||||
|
that activates the component. The scope of these permissions can be further
|
||||||
|
limited by the <code><a
|
||||||
|
href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
|
||||||
|
<grant-uri-permission element></a></code>.</p>
|
||||||
|
|
||||||
|
<p>When accessing a content provider, use parameterized query methods such as
|
||||||
|
{@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()},
|
||||||
|
{@link android.content.ContentProvider#update(Uri,ContentValues,String,String[]) update()}, and
|
||||||
|
{@link android.content.ContentProvider#delete(Uri,String,String[]) delete()} to avoid
|
||||||
|
potential SQL injection from untrusted sources. Note that using parameterized methods is not
|
||||||
|
sufficient if the <code>selection</code> argument is built by concatenating user data
|
||||||
|
prior to submitting it to the method.</p>
|
||||||
|
|
||||||
|
<p>Do not have a false sense of security about the write permission. Consider
|
||||||
|
that the write permission allows SQL statements which make it possible for some
|
||||||
|
data to be confirmed using creative <code>WHERE</code> clauses and parsing the
|
||||||
|
results. For example, an attacker might probe for presence of a specific phone
|
||||||
|
number in a call-log by modifying a row only if that phone number already
|
||||||
|
exists. If the content provider data has predictable structure, the write
|
||||||
|
permission may be equivalent to providing both reading and writing.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Permissions">Using Permissions</h2>
|
||||||
|
|
||||||
|
<p>Because Android sandboxes applications from each other, applications must explicitly
|
||||||
|
share resources and data. They do this by declaring the permissions they need for additional
|
||||||
|
capabilities not provided by the basic sandbox, including access to device features such as
|
||||||
|
the camera.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="RequestingPermissions">Requesting Permissions</h3>
|
||||||
|
|
||||||
|
<p>We recommend minimizing the number of permissions that your app requests
|
||||||
|
Not having access to sensitive permissions reduces the risk of
|
||||||
|
inadvertently misusing those permissions, can improve user adoption, and makes
|
||||||
|
your app less for attackers. Generally,
|
||||||
|
if a permission is not required for your app to function, do not request it.</p>
|
||||||
|
|
||||||
|
<p>If it's possible to design your application in a way that does not require
|
||||||
|
any permissions, that is preferable. For example, rather than requesting access
|
||||||
|
to device information to create a unique identifier, create a <a
|
||||||
|
href="{@docRoot}reference/java/util/UUID.html">GUID</a> for your application
|
||||||
|
(see the section about <a href="#UserData">Handling User Data</a>). Or, rather than
|
||||||
|
using external storage (which requires permission), store data
|
||||||
|
on the internal storage.</p>
|
||||||
|
|
||||||
|
<p>In addition to requesting permissions, your application can use the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/permission-element.html">{@code <permissions>}</a>
|
||||||
|
to protect IPC that is security sensitive and will be exposed to other
|
||||||
|
applications, such as a {@link android.content.ContentProvider}.
|
||||||
|
In general, we recommend using access controls
|
||||||
|
other than user confirmed permissions where possible because permissions can
|
||||||
|
be confusing for users. For example, consider using the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
|
||||||
|
protection level</a> on permissions for IPC communication between applications
|
||||||
|
provided by a single developer.</p>
|
||||||
|
|
||||||
|
<p>Do not leak permission-protected data. This occurs when your app exposes data
|
||||||
|
over IPC that is only available because it has a specific permission, but does
|
||||||
|
not require that permission of any clients of it’s IPC interface. More
|
||||||
|
details on the potential impacts, and frequency of this type of problem is
|
||||||
|
provided in this research paper published at USENIX: <a
|
||||||
|
href="http://www.cs.berkeley.edu/~afelt/felt_usenixsec2011.pdf">http://www.cs.be
|
||||||
|
rkeley.edu/~afelt/felt_usenixsec2011.pdf</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="CreatingPermissions">Creating Permissions</h3>
|
||||||
|
|
||||||
|
<p>Generally, you should strive to define as few permissions as possible while
|
||||||
|
satisfying your security requirements. Creating a new permission is relatively
|
||||||
|
uncommon for most applications, because the <a
|
||||||
|
href="{@docRoot}reference/android/Manifest.permission.html">system-defined
|
||||||
|
permissions</a> cover many situations. Where appropriate,
|
||||||
|
perform access checks using existing permissions.</p>
|
||||||
|
|
||||||
|
<p>If you must create a new permission, consider whether you can accomplish
|
||||||
|
your task with a <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">"signature"
|
||||||
|
protection level</a>. Signature permissions are transparent
|
||||||
|
to the user and only allow access by applications signed by the same developer
|
||||||
|
as application performing the permission check.</p>
|
||||||
|
|
||||||
|
<p>If you create a permission with the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">"dangerous"
|
||||||
|
protection level</a>, there are a number of complexities
|
||||||
|
that you need to consider:
|
||||||
|
<ul>
|
||||||
|
<li>The permission must have a string that concisely expresses to a user the
|
||||||
|
security decision they will be required to make.</li>
|
||||||
|
<li>The permission string must be localized to many different languages.</li>
|
||||||
|
<li>Users may choose not to install an application because a permission is
|
||||||
|
confusing or perceived as risky.</li>
|
||||||
|
<li>Applications may request the permission when the creator of the permission
|
||||||
|
has not been installed.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Each of these poses a significant non-technical challenge for you as the developer
|
||||||
|
while also confusing your users,
|
||||||
|
which is why we discourage the use of the "dangerous" permission level.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Networking">Using Networking</h2>
|
||||||
|
|
||||||
|
<p>Network transactions are inherently risky for security, because it involves transmitting
|
||||||
|
data that is potentially private to the user. People are increasingly aware of the privacy
|
||||||
|
concerns of a mobile device, especially when the device performs network transactions,
|
||||||
|
so it's very important that your app implement all best practices toward keeping the user's
|
||||||
|
data secure at all times.</p>
|
||||||
|
|
||||||
|
<h3 id="IPNetworking">Using IP Networking</h3>
|
||||||
|
|
||||||
|
<p>Networking on Android is not significantly different from other Linux
|
||||||
|
environments. The key consideration is making sure that appropriate protocols
|
||||||
|
are used for sensitive data, such as {@link javax.net.ssl.HttpsURLConnection} for
|
||||||
|
secure web traffic. We prefer use of HTTPS over HTTP anywhere that HTTPS is
|
||||||
|
supported on the server, because mobile devices frequently connect on networks
|
||||||
|
that are not secured, such as public Wi-Fi hotspots.</p>
|
||||||
|
|
||||||
|
<p>Authenticated, encrypted socket-level communication can be easily
|
||||||
|
implemented using the {@link javax.net.ssl.SSLSocket}
|
||||||
|
class. Given the frequency with which Android devices connect to unsecured
|
||||||
|
wireless networks using Wi-Fi, the use of secure networking is strongly
|
||||||
|
encouraged for all applications that communicate over the network.</p>
|
||||||
|
|
||||||
|
<p>We have seen some applications use <a
|
||||||
|
href="http://en.wikipedia.org/wiki/Localhost">localhost</a> network ports for
|
||||||
|
handling sensitive IPC. We discourage this approach since these interfaces are
|
||||||
|
accessible by other applications on the device. Instead, you should use an Android IPC
|
||||||
|
mechanism where authentication is possible such as with a {@link android.app.Service}. (Even
|
||||||
|
worse than using loopback is to bind to INADDR_ANY since then your application
|
||||||
|
may receive requests from anywhere.)</p>
|
||||||
|
|
||||||
|
<p>Also, one common issue that warrants repeating is to make sure that you do
|
||||||
|
not trust data downloaded from HTTP or other insecure protocols. This includes
|
||||||
|
validation of input in {@link android.webkit.WebView} and
|
||||||
|
any responses to intents issued against HTTP.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Using Telephony Networking</h3>
|
||||||
|
|
||||||
|
<p>The <acronym title="Short Message Service">SMS</acronym> protocol was primarily designed for
|
||||||
|
user-to-user communication and is not well-suited for apps that want to transfer data.
|
||||||
|
Due to the limitations of SMS, we strongly recommend the use of <a
|
||||||
|
href="{@docRoot}guide/google/gcm/index.html">Google Cloud Messaging</a> (GCM)
|
||||||
|
and IP networking for sending data messages from a web server to your app on a user device.</p>
|
||||||
|
|
||||||
|
<p>Beware that SMS is neither encrypted nor strongly
|
||||||
|
authenticated on either the network or the device. In particular, any SMS receiver
|
||||||
|
should expect that a malicious user may have sent the SMS to your application—Do
|
||||||
|
not rely on unauthenticated SMS data to perform sensitive commands.
|
||||||
|
Also, you should be aware that SMS may be subject to spoofing and/or
|
||||||
|
interception on the network. On the Android-powered device itself, SMS
|
||||||
|
messages are transmitted as broadcast intents, so they may be read or captured
|
||||||
|
by other applications that have the {@link android.Manifest.permission#READ_SMS}
|
||||||
|
permission.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="InputValidation">Performing Input Validation</h2>
|
||||||
|
|
||||||
|
<p>Insufficient input validation is one of the most common security problems
|
||||||
|
affecting applications, regardless of what platform they run on. Android does
|
||||||
|
have platform-level countermeasures that reduce the exposure of applications to
|
||||||
|
input validation issues and you should use those features where possible. Also
|
||||||
|
note that selection of type-safe languages tends to reduce the likelihood of
|
||||||
|
input validation issues.</p>
|
||||||
|
|
||||||
|
<p>If you are using native code, then any data read from files, received over
|
||||||
|
the network, or received from an IPC has the potential to introduce a security
|
||||||
|
issue. The most common problems are <a
|
||||||
|
href="http://en.wikipedia.org/wiki/Buffer_overflow">buffer overflows</a>, <a
|
||||||
|
href="http://en.wikipedia.org/wiki/Double_free#Use_after_free">use after
|
||||||
|
free</a>, and <a
|
||||||
|
href="http://en.wikipedia.org/wiki/Off-by-one_error">off-by-one errors</a>.
|
||||||
|
Android provides a number of technologies like <acronym
|
||||||
|
title="Address Space Layout Randomization">ASLR</acronym> and <acronym
|
||||||
|
title="Data Execution Prevention">DEP</acronym> that reduce the
|
||||||
|
exploitability of these errors, but they do not solve the underlying problem.
|
||||||
|
You can prevent these vulneratbilities by careful handling pointers and managing
|
||||||
|
buffers.</p>
|
||||||
|
|
||||||
|
<p>Dynamic, string based languages such as JavaScript and SQL are also subject
|
||||||
|
to input validation problems due to escape characters and <a
|
||||||
|
href="http://en.wikipedia.org/wiki/Code_injection">script injection</a>.</p>
|
||||||
|
|
||||||
|
<p>If you are using data within queries that are submitted to an SQL database or a
|
||||||
|
content provider, SQL injection may be an issue. The best defense is to use
|
||||||
|
parameterized queries, as is discussed in the above section about <a
|
||||||
|
href="#ContentProviders">content providers</a>.
|
||||||
|
Limiting permissions to read-only or write-only can also reduce the potential
|
||||||
|
for harm related to SQL injection.</p>
|
||||||
|
|
||||||
|
<p>If you cannot use the security features above, we strongly recommend the use
|
||||||
|
of well-structured data formats and verifying that the data conforms to the
|
||||||
|
expected format. While blacklisting of characters or character-replacement can
|
||||||
|
be an effective strategy, these techniques are error-prone in practice and
|
||||||
|
should be avoided when possible.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="UserData">Handling User Data</h2>
|
||||||
|
|
||||||
|
<p>In general, the best approach for user data security is to minimize the use of APIs that access
|
||||||
|
sensitive or personal user data. If you have access to user data and can avoid
|
||||||
|
storing or transmitting the information, do not store or transmit the data.
|
||||||
|
Finally, consider if there is a way that your application logic can be
|
||||||
|
implemented using a hash or non-reversible form of the data. For example, your
|
||||||
|
application might use the hash of an an email address as a primary key, to
|
||||||
|
avoid transmitting or storing the email address. This reduces the chances of
|
||||||
|
inadvertently exposing data, and it also reduces the chance of attackers
|
||||||
|
attempting to exploit your application.</p>
|
||||||
|
|
||||||
|
<p>If your application accesses personal information such as passwords or
|
||||||
|
usernames, keep in mind that some jurisdictions may require you to provide a
|
||||||
|
privacy policy explaining your use and storage of that data. So following the
|
||||||
|
security best practice of minimizing access to user data may also simplify
|
||||||
|
compliance.</p>
|
||||||
|
|
||||||
|
<p>You should also consider whether your application might be inadvertently
|
||||||
|
exposing personal information to other parties such as third-party components
|
||||||
|
for advertising or third-party services used by your application. If you don't
|
||||||
|
know why a component or service requires a personal information, don’t
|
||||||
|
provide it. In general, reducing the access to personal information by your
|
||||||
|
application will reduce the potential for problems in this area.</p>
|
||||||
|
|
||||||
|
<p>If access to sensitive data is required, evaluate whether that information
|
||||||
|
must be transmitted to a server, or whether the operation can be performed on
|
||||||
|
the client. Consider running any code using sensitive data on the client to
|
||||||
|
avoid transmitting user data.</p>
|
||||||
|
|
||||||
|
<p>Also, make sure that you do not inadvertently expose user data to other
|
||||||
|
application on the device through overly permissive IPC, world writable files,
|
||||||
|
or network sockets. This is a special case of leaking permission-protected data,
|
||||||
|
discussed in the <a href="#RequestingPermissions">Requesting Permissions</a> section.</p>
|
||||||
|
|
||||||
|
<p>If a <acronym title="Globally Unique Identifier">GUID</acronym>
|
||||||
|
is required, create a large, unique number and store it. Do not
|
||||||
|
use phone identifiers such as the phone number or IMEI which may be associated
|
||||||
|
with personal information. This topic is discussed in more detail in the <a
|
||||||
|
href="http://android-developers.blogspot.com/2011/03/identifying-app-installations.html">Android
|
||||||
|
Developer Blog</a>.</p>
|
||||||
|
|
||||||
|
<p>Be careful when writing to on-device logs.
|
||||||
|
In Android, logs are a shared resource, and are available
|
||||||
|
to an application with the {@link android.Manifest.permission#READ_LOGS} permission.
|
||||||
|
Even though the phone log data
|
||||||
|
is temporary and erased on reboot, inappropriate logging of user information
|
||||||
|
could inadvertently leak user data to other applications.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="WebView">Using WebView</h2>
|
||||||
|
|
||||||
|
<p>Because {@link android.webkit.WebView} consumes web content that can include HTML and JavaScript,
|
||||||
|
improper use can introduce common web security issues such as <a
|
||||||
|
href="http://en.wikipedia.org/wiki/Cross_site_scripting">cross-site-scripting</a>
|
||||||
|
(JavaScript injection). Android includes a number of mechanisms to reduce
|
||||||
|
the scope of these potential issues by limiting the capability of {@link android.webkit.WebView} to
|
||||||
|
the minimum functionality required by your application.</p>
|
||||||
|
|
||||||
|
<p>If your application does not directly use JavaScript within a {@link android.webkit.WebView}, do
|
||||||
|
<em>not</em> call {@link android.webkit.WebSettings#setJavaScriptEnabled setJavaScriptEnabled()}.
|
||||||
|
Some sample code uses this method, which you might repurpose in production
|
||||||
|
application, so remove that method call if it's not required. By default,
|
||||||
|
{@link android.webkit.WebView} does
|
||||||
|
not execute JavaScript so cross-site-scripting is not possible.</p>
|
||||||
|
|
||||||
|
<p>Use {@link android.webkit.WebView#addJavascriptInterface
|
||||||
|
addJavaScriptInterface()} with
|
||||||
|
particular care because it allows JavaScript to invoke operations that are
|
||||||
|
normally reserved for Android applications. If you use it, expose
|
||||||
|
{@link android.webkit.WebView#addJavascriptInterface addJavaScriptInterface()} only to
|
||||||
|
web pages from which all input is trustworthy. If untrusted input is allowed,
|
||||||
|
untrusted JavaScript may be able to invoke Android methods within your app. In general, we
|
||||||
|
recommend exposing {@link android.webkit.WebView#addJavascriptInterface
|
||||||
|
addJavaScriptInterface()} only to JavaScript that is contained within your application APK.</p>
|
||||||
|
|
||||||
|
<p>If your application accesses sensitive data with a
|
||||||
|
{@link android.webkit.WebView}, you may want to use the
|
||||||
|
{@link android.webkit.WebView#clearCache clearCache()} method to delete any files stored
|
||||||
|
locally. Server-side
|
||||||
|
headers like <code>no-cache</code> can also be used to indicate that an application should
|
||||||
|
not cache particular content.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="Credentials">Handling Credentials</h3>
|
||||||
|
|
||||||
|
<p>In general, we recommend minimizing the frequency of asking for user
|
||||||
|
credentials—to make phishing attacks more conspicuous, and less likely to be
|
||||||
|
successful. Instead use an authorization token and refresh it.</p>
|
||||||
|
|
||||||
|
<p>Where possible, username and password should not be stored on the device.
|
||||||
|
Instead, perform initial authentication using the username and password
|
||||||
|
supplied by the user, and then use a short-lived, service-specific
|
||||||
|
authorization token.</p>
|
||||||
|
|
||||||
|
<p>Services that will be accessible to multiple applications should be accessed
|
||||||
|
using {@link android.accounts.AccountManager}. If possible, use the
|
||||||
|
{@link android.accounts.AccountManager} class to invoke a cloud-based service and do not store
|
||||||
|
passwords on the device.</p>
|
||||||
|
|
||||||
|
<p>After using {@link android.accounts.AccountManager} to retrieve an
|
||||||
|
{@link android.accounts.Account}, {@link android.accounts.Account#CREATOR}
|
||||||
|
before passing in any credentials, so that you do not inadvertently pass
|
||||||
|
credentials to the wrong application.</p>
|
||||||
|
|
||||||
|
<p>If credentials are to be used only by applications that you create, then you
|
||||||
|
can verify the application which accesses the {@link android.accounts.AccountManager} using
|
||||||
|
{@link android.content.pm.PackageManager#checkSignatures checkSignature()}.
|
||||||
|
Alternatively, if only one application will use the credential, you might use a
|
||||||
|
{@link java.security.KeyStore} for storage.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Crypto">Using Cryptography</h2>
|
||||||
|
|
||||||
|
<p>In addition to providing data isolation, supporting full-filesystem
|
||||||
|
encryption, and providing secure communications channels, Android provides a
|
||||||
|
wide array of algorithms for protecting data using cryptography.</p>
|
||||||
|
|
||||||
|
<p>In general, try to use the highest level of pre-existing framework
|
||||||
|
implementation that can support your use case. If you need to securely
|
||||||
|
retrieve a file from a known location, a simple HTTPS URI may be adequate and
|
||||||
|
requires no knowledge of cryptography. If you need a secure
|
||||||
|
tunnel, consider using {@link javax.net.ssl.HttpsURLConnection} or
|
||||||
|
{@link javax.net.ssl.SSLSocket}, rather than writing your own protocol.</p>
|
||||||
|
|
||||||
|
<p>If you do find yourself needing to implement your own protocol, we strongly
|
||||||
|
recommend that you <em>not</em> implement your own cryptographic algorithms. Use
|
||||||
|
existing cryptographic algorithms such as those in the implementation of AES or
|
||||||
|
RSA provided in the {@link javax.crypto.Cipher} class.</p>
|
||||||
|
|
||||||
|
<p>Use a secure random number generator, {@link java.security.SecureRandom},
|
||||||
|
to initialize any cryptographic keys, {@link javax.crypto.KeyGenerator}.
|
||||||
|
Use of a key that is not generated with a secure random
|
||||||
|
number generator significantly weakens the strength of the algorithm, and may
|
||||||
|
allow offline attacks.</p>
|
||||||
|
|
||||||
|
<p>If you need to store a key for repeated use, use a mechanism like
|
||||||
|
{@link java.security.KeyStore} that
|
||||||
|
provides a mechanism for long term storage and retrieval of cryptographic
|
||||||
|
keys.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="IPC">Using Interprocess Communication</h2>
|
||||||
|
|
||||||
|
<p>Some apps attempt to implement IPC using traditional Linux
|
||||||
|
techniques such as network sockets and shared files. We strongly encourage you to instead
|
||||||
|
use Android system functionality for IPC such as {@link android.content.Intent},
|
||||||
|
{@link android.os.Binder} or {@link android.os.Messenger} with a {@link
|
||||||
|
android.app.Service}, and {@link android.content.BroadcastReceiver}.
|
||||||
|
The Android IPC mechanisms allow you to verify the identity of
|
||||||
|
the application connecting to your IPC and set security policy for each IPC
|
||||||
|
mechanism.</p>
|
||||||
|
|
||||||
|
<p>Many of the security elements are shared across IPC mechanisms.
|
||||||
|
If your IPC mechanism is not intended for use by other applications, set the
|
||||||
|
{@code android:exported} attribute to {@code "false"} in the component's manifest element,
|
||||||
|
such as for the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code <service>}</a>
|
||||||
|
element. This is useful for applications that consist of multiple processes
|
||||||
|
within the same UID, or if you decide late in development that you do not
|
||||||
|
actually want to expose functionality as IPC but you don’t want to rewrite
|
||||||
|
the code.</p>
|
||||||
|
|
||||||
|
<p>If your IPC is intended to be accessible to other applications, you can
|
||||||
|
apply a security policy by using the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/permission-element.html">{@code <permission>}</a>
|
||||||
|
element. If IPC is between your own separate apps that are signed with the same key,
|
||||||
|
it is preferable to use {@code "signature"} level permission in the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">{@code
|
||||||
|
android:protectionLevel}</a>.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Using intents</h3>
|
||||||
|
|
||||||
|
<p>Intents are the preferred mechanism for asynchronous IPC in Android.
|
||||||
|
Depending on your application requirements, you might use {@link
|
||||||
|
android.content.Context#sendBroadcast sendBroadcast()}, {@link
|
||||||
|
android.content.Context#sendOrderedBroadcast sendOrderedBroadcast()},
|
||||||
|
or an explicit intent to a specific application component.</p>
|
||||||
|
|
||||||
|
<p>Note that ordered broadcasts can be “consumed” by a recipient, so they
|
||||||
|
may not be delivered to all applications. If you are sending an intent that muse be delivered
|
||||||
|
to a specific receiver, then you must use an explicit intent that declares the receiver
|
||||||
|
by nameintent.</p>
|
||||||
|
|
||||||
|
<p>Senders of an intent can verify that the recipient has a permission
|
||||||
|
specifying a non-Null permission with the method call. Only applications with that
|
||||||
|
permission will receive the intent. If data within a broadcast intent may be
|
||||||
|
sensitive, you should consider applying a permission to make sure that
|
||||||
|
malicious applications cannot register to receive those messages without
|
||||||
|
appropriate permissions. In those circumstances, you may also consider
|
||||||
|
invoking the receiver directly, rather than raising a broadcast.</p>
|
||||||
|
|
||||||
|
<p class="note"><strong>Note:</strong> Intent filters should not be considered
|
||||||
|
a security feature—components
|
||||||
|
can be invoked with explicit intents and may not have data that would conform to the intent
|
||||||
|
filter. You should perform input validation within your intent receiver to
|
||||||
|
confirm that it is properly formatted for the invoked receiver, service, or
|
||||||
|
activity.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="Services">Using services</h3>
|
||||||
|
|
||||||
|
<p>A {@link android.app.Service} is often used to supply functionality for other applications to
|
||||||
|
use. Each service class must have a corresponding <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> declaration in its
|
||||||
|
manifest file.</p>
|
||||||
|
|
||||||
|
<p>By default, services are not exported and cannot be invoked by any other
|
||||||
|
application. However, if you add any intent filters to the service declaration, then it is exported
|
||||||
|
by default. It's best if you explicitly declare the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code
|
||||||
|
android:exported}</a> attribute to be sure it behaves as you'd like.
|
||||||
|
Services can also be protected using the <a
|
||||||
|
href="{@docRoot}guide/topics/manifest/service-element.html#prmsn">{@code android:permission}</a>
|
||||||
|
attribute. By doing so, other applications will need to declare
|
||||||
|
a corresponding <code><a
|
||||||
|
href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a>
|
||||||
|
</code> element in their own manifest to be
|
||||||
|
able to start, stop, or bind to the service.</p>
|
||||||
|
|
||||||
|
<p>A service can protect individual IPC calls into it with permissions, by
|
||||||
|
calling {@link android.content.Context#checkCallingPermission
|
||||||
|
checkCallingPermission()} before executing
|
||||||
|
the implementation of that call. We generally recommend using the
|
||||||
|
declarative permissions in the manifest, since those are less prone to
|
||||||
|
oversight.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Using binder and messenger interfaces</h3>
|
||||||
|
|
||||||
|
<p>Using {@link android.os.Binder} or {@link android.os.Messenger} is the
|
||||||
|
preferred mechanism for RPC-style IPC in Android. They provide a well-defined
|
||||||
|
interface that enables mutual authentication of the endpoints, if required.</p>
|
||||||
|
|
||||||
|
<p>We strongly encourage designing interfaces in a manner that does not require
|
||||||
|
interface specific permission checks. {@link android.os.Binder} and
|
||||||
|
{@link android.os.Messenger} objects are not declared within the
|
||||||
|
application manifest, and therefore you cannot apply declarative permissions
|
||||||
|
directly to them. They generally inherit permissions declared in the
|
||||||
|
application manifest for the {@link android.app.Service} or {@link
|
||||||
|
android.app.Activity} within which they are
|
||||||
|
implemented. If you are creating an interface that requires authentication
|
||||||
|
and/or access controls, those controls must be
|
||||||
|
explicitly added as code in the {@link android.os.Binder} or {@link android.os.Messenger}
|
||||||
|
interface.</p>
|
||||||
|
|
||||||
|
<p>If providing an interface that does require access controls, use {@link
|
||||||
|
android.content.Context#checkCallingPermission checkCallingPermission()}
|
||||||
|
to verify whether the
|
||||||
|
caller has a required permission. This is especially important
|
||||||
|
before accessing a service on behalf of the caller, as the identify of your
|
||||||
|
application is passed to other interfaces. If invoking an interface provided
|
||||||
|
by a {@link android.app.Service}, the {@link
|
||||||
|
android.content.Context#bindService bindService()}
|
||||||
|
invocation may fail if you do not have permission to access the given service.
|
||||||
|
If calling an interface provided locally by your own application, it may be
|
||||||
|
useful to use the {@link android.os.Binder#clearCallingIdentity clearCallingIdentity()}
|
||||||
|
to satisfy internal security checks.</p>
|
||||||
|
|
||||||
|
<p>For more information about performing IPC with a service, see
|
||||||
|
<a href="{@docRoot}guide/components/bound-services.html">Bound Services</a>.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="BroadcastReceivers">Using broadcast receivers</h3>
|
||||||
|
|
||||||
|
<p>A {@link android.content.BroadcastReceiver} handles asynchronous requests initiated by
|
||||||
|
an {@link android.content.Intent}.</p>
|
||||||
|
|
||||||
|
<p>By default, receivers are exported and can be invoked by any other
|
||||||
|
application. If your {@link android.content.BroadcastReceiver}
|
||||||
|
is intended for use by other applications, you
|
||||||
|
may want to apply security permissions to receivers using the <code><a
|
||||||
|
href="{@docRoot}guide/topics/manifest/receiver-element.html">
|
||||||
|
<receiver></a></code> element within the application manifest. This will
|
||||||
|
prevent applications without appropriate permissions from sending an intent to
|
||||||
|
the {@link android.content.BroadcastReceiver}.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="DynamicCode">Dynamically Loading Code</h2>
|
||||||
|
|
||||||
|
<p>We strongly discourage loading code from outside of your application APK.
|
||||||
|
Doing so significantly increases the likelihood of application compromise due
|
||||||
|
to code injection or code tampering. It also adds complexity around version
|
||||||
|
management and application testing. Finally, it can make it impossible to
|
||||||
|
verify the behavior of an application, so it may be prohibited in some
|
||||||
|
environments.</p>
|
||||||
|
|
||||||
|
<p>If your application does dynamically load code, the most important thing to
|
||||||
|
keep in mind about dynamically loaded code is that it runs with the same
|
||||||
|
security permissions as the application APK. The user made a decision to
|
||||||
|
install your application based on your identity, and they are expecting that
|
||||||
|
you provide any code run within the application, including code that is
|
||||||
|
dynamically loaded.</p>
|
||||||
|
|
||||||
|
<p>The major security risk associated with dynamically loading code is that the
|
||||||
|
code needs to come from a verifiable source. If the modules are included
|
||||||
|
directly within your APK, then they cannot be modified by other applications.
|
||||||
|
This is true whether the code is a native library or a class being loaded using
|
||||||
|
{@link dalvik.system.DexClassLoader}. We have seen many instances of applications
|
||||||
|
attempting to load code from insecure locations, such as downloaded from the
|
||||||
|
network over unencrypted protocols or from world writable locations such as
|
||||||
|
external storage. These locations could allow someone on the network to modify
|
||||||
|
the content in transit, or another application on a users device to modify the
|
||||||
|
content on the device, respectively.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Dalvik">Security in a Virtual Machine</h2>
|
||||||
|
|
||||||
|
<p>Dalvik is Android's runtime virtual machine (VM). Dalvik was built specifically for Android,
|
||||||
|
but many of the concerns regarding secure code in other virtual machines also apply to Android.
|
||||||
|
In general, you shouldn't concern yourself with security issues relating to the virtual machine.
|
||||||
|
Your application runs in a secure sandbox environment, so other processes on the system cannnot
|
||||||
|
access your code or private data.</p>
|
||||||
|
|
||||||
|
<p>If you're interested in diving deeper on the subject of virtual machine security,
|
||||||
|
we recommend that you familiarize yourself with some
|
||||||
|
existing literature on the subject. Two of the more popular resources are:
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://www.securingjava.com/toc.html">
|
||||||
|
http://www.securingjava.com/toc.html</a></li>
|
||||||
|
<li><a
|
||||||
|
href="https://www.owasp.org/index.php/Java_Security_Resources">
|
||||||
|
https://www.owasp.org/index.php/Java_Security_Resources</a></li>
|
||||||
|
</ul></p>
|
||||||
|
|
||||||
|
<p>This document is focused on the areas which are Android specific or
|
||||||
|
different from other VM environments. For developers experienced with VM
|
||||||
|
programming in other environments, there are two broad issues that may be
|
||||||
|
different about writing apps for Android:
|
||||||
|
<ul>
|
||||||
|
<li>Some virtual machines, such as the JVM or .net runtime, act as a security
|
||||||
|
boundary, isolating code from the underlying operating system capabilities. On
|
||||||
|
Android, the Dalvik VM is not a security boundary—the application sandbox is
|
||||||
|
implemented at the OS level, so Dalvik can interoperate with native code in the
|
||||||
|
same application without any security constraints.</li>
|
||||||
|
|
||||||
|
<li>Given the limited storage on mobile devices, it’s common for developers
|
||||||
|
to want to build modular applications and use dynamic class loading. When
|
||||||
|
doing this, consider both the source where you retrieve your application logic
|
||||||
|
and where you store it locally. Do not use dynamic class loading from sources
|
||||||
|
that are not verified, such as unsecured network sources or external storage,
|
||||||
|
because that code might be modified to include malicious behavior.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="Native">Security in Native Code</h2>
|
||||||
|
|
||||||
|
<p>In general, we encourage developers to use the Android SDK for
|
||||||
|
application development, rather than using native code with the
|
||||||
|
<a href="{@docRoot}tools/sdk/ndk/index.html">Android NDK</a>. Applications built
|
||||||
|
with native code are more complex, less portable, and more like to include
|
||||||
|
common memory corruption errors such as buffer overflows.</p>
|
||||||
|
|
||||||
|
<p>Android is built using the Linux kernel and being familiar with Linux
|
||||||
|
development security best practices is especially useful if you are going to
|
||||||
|
use native code. Linux security practices are beyond the scope of this document,
|
||||||
|
but one of the most popular resources is “Secure Programming for
|
||||||
|
Linux and Unix HOWTO”, available at <a
|
||||||
|
href="http://www.dwheeler.com/secure-programs">
|
||||||
|
http://www.dwheeler.com/secure-programs</a>.</p>
|
||||||
|
|
||||||
|
<p>An important difference between Android and most Linux environments is the
|
||||||
|
Application Sandbox. On Android, all applications run in the Application
|
||||||
|
Sandbox, including those written with native code. At the most basic level, a
|
||||||
|
good way to think about it for developers familiar with Linux is to know that
|
||||||
|
every application is given a unique <acronym title="User Identifier">UID</acronym>
|
||||||
|
with very limited permissions. This is discussed in more detail in the <a
|
||||||
|
href="http://source.android.com/tech/security/index.html">Android Security
|
||||||
|
Overview</a> and you should be familiar with application permissions even if
|
||||||
|
you are using native code.</p>
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user