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">
|
||||
<span class="en">Supporting Tablets and Handsets</span>
|
||||
</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>
|
||||
</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.
|
||||
|
||||
@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
|
||||
snippets and sample code for you to use in your apps.</p>
|
||||
<p>Welcome to Training. Each class provides a series of lessons that
|
||||
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
|
||||
on Android, you should walk through each of these classes, beginning with
|
||||
<a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>.</p></a>
|
||||
<p>This first group, <em>Getting Started</em>, teaches you the bare
|
||||
essentials for Android app development.
|
||||
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
|
||||
@jd:body
|
||||
|
||||
<div id="qv-wrapper">
|
||||
<div id="qv">
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>In this document</h2>
|
||||
<ol>
|
||||
@@ -1,21 +1,20 @@
|
||||
page.title=Designing for Performance
|
||||
page.title=Performance Tips
|
||||
@jd:body
|
||||
|
||||
<div id="qv-wrapper">
|
||||
<div id="qv">
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<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="#ObjectCreation">Avoid Creating Unnecessary Objects</a></li>
|
||||
<li><a href="#PreferStatic">Prefer Static Over Virtual</a></li>
|
||||
<li><a href="#UseFinal">Use Static Final For Constants</a></li>
|
||||
<li><a href="#GettersSetters">Avoid Internal Getters/Setters</a></li>
|
||||
<li><a href="#Loops">Use Enhanced For Loop Syntax</a></li>
|
||||
<li><a href="#PackageInner">Consider Package Instead of Private Access with Private Inner Classes</a></li>
|
||||
<li><a href="#AvoidFloat">Avoid Using Floating-Point</a></li>
|
||||
<li><a href="#UseLibraries">Know and Use the Libraries</a></li>
|
||||
<li><a href="#NativeMethods">Use Native Methods Carefully</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>
|
||||
@@ -24,20 +23,12 @@ page.title=Designing for Performance
|
||||
</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>This document primarily covers micro-optimizations that can improve overall app performance
|
||||
when combined, but it's unlikely that these changes will result in dramatic
|
||||
performance effects. Choosing the right algorithms and data structures should always be your
|
||||
priority, but is outside the scope of this document. You should use the tips in this document
|
||||
as general coding practices that you can incorporate into your habits for general code
|
||||
efficiency.</p>
|
||||
|
||||
<p>There are two basic rules for writing efficient code:</p>
|
||||
<ul>
|
||||
@@ -45,52 +36,31 @@ outside the scope of this document.</p>
|
||||
<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
|
||||
app is that your app is certain to be running on multiple types of
|
||||
hardware. 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"
|
||||
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
|
||||
without.</p>
|
||||
|
||||
<p>If you want to know how your app performs on a given device, you need to
|
||||
test on that device.</p>
|
||||
<p>To ensure your app performs well across a wide variety of devices, ensure
|
||||
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
|
||||
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
|
||||
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>
|
||||
|
||||
<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>
|
||||
<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,
|
||||
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[]
|
||||
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
|
||||
part of the original input, you'll be keeping it all around in memory
|
||||
anyway if you go this route.)</li>
|
||||
@@ -113,16 +83,18 @@ examples of things that can help:</p>
|
||||
parallel single one-dimension arrays:</p>
|
||||
|
||||
<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
|
||||
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>
|
||||
<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.
|
||||
|
||||
<li>If you need to implement a container that stores tuples of {@code (Foo,Bar)}
|
||||
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
|
||||
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
|
||||
other code to access. In those cases, it's usually better to make a small
|
||||
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>
|
||||
</ul>
|
||||
|
||||
@@ -130,66 +102,28 @@ parallel single one-dimension arrays:</p>
|
||||
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>
|
||||
<h2 id="PreferStatic">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>
|
||||
<h2 id="UseFinal">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>
|
||||
<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.
|
||||
@@ -200,84 +134,125 @@ 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>
|
||||
<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>
|
||||
field lookup.</p>
|
||||
|
||||
<a name="foreach" id="foreach"></a>
|
||||
<h2>Use Enhanced For Loop Syntax</h2>
|
||||
<p class="note"><strong>Note:</strong> This optimization applies only to primitive types and
|
||||
{@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
|
||||
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
|
||||
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 = ...
|
||||
<pre>
|
||||
static class Foo {
|
||||
int mSplat;
|
||||
}
|
||||
|
||||
public void zero() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < mArray.length; ++i) {
|
||||
sum += mArray[i].mSplat;
|
||||
}
|
||||
}
|
||||
Foo[] mArray = ...
|
||||
|
||||
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 zero() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < mArray.length; ++i) {
|
||||
sum += mArray[i].mSplat;
|
||||
}
|
||||
}
|
||||
|
||||
public void two() {
|
||||
int sum = 0;
|
||||
for (Foo a : mArray) {
|
||||
sum += a.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
|
||||
<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
|
||||
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
|
||||
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.
|
||||
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>So, you should use the enhanced <code>for</code> loop by default, but consider a
|
||||
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>
|
||||
|
||||
<pre>public class Foo {
|
||||
<pre>
|
||||
public class Foo {
|
||||
private class Inner {
|
||||
void stuff() {
|
||||
Foo.this.doStuff(Foo.this.mValue);
|
||||
@@ -297,7 +272,7 @@ hand-written counted loop for performance-critical ArrayList iteration.</p>
|
||||
}
|
||||
}</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
|
||||
instance field in the outer class. This is legal, and the code prints "Value is
|
||||
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
|
||||
methods:</p>
|
||||
|
||||
<pre>/*package*/ static int Foo.access$100(Foo foo) {
|
||||
<pre>
|
||||
/*package*/ static int Foo.access$100(Foo foo) {
|
||||
return foo.mValue;
|
||||
}
|
||||
/*package*/ static void Foo.access$200(Foo foo, int value) {
|
||||
@@ -317,7 +293,7 @@ methods:</p>
|
||||
}</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
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
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>
|
||||
Android-powered devices.</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
|
||||
<p>Also, even for integers, some processors 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
|
||||
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>
|
||||
|
||||
|
||||
|
||||
<h2 id="UseLibraries">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
|
||||
here is {@link java.lang.String#indexOf String.indexOf()} and
|
||||
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>
|
||||
|
||||
<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 class="note"><strong>Tip:</strong>
|
||||
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
|
||||
optimize across these boundaries. If you're allocating native resources (memory
|
||||
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>
|
||||
|
||||
<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
|
||||
<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>
|
||||
|
||||
<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
|
||||
<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
|
||||
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.
|
||||
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