docs: Battery performance, networking analysis and optimization

- added draft TOC structure to training
- added battery/networking training pages

Change-Id: I0136898f37feac9a8ea17de24ea5ef1bf0ce5329
This commit is contained in:
Joe Fernandez
2015-10-17 11:05:04 -07:00
committed by Doug Kramer
parent b0eb73c83e
commit 28be3259d9
12 changed files with 1060 additions and 7 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

@@ -1,5 +1,8 @@
page.title=Optimizing Battery Life
page.tags=network,internet
page.tags=battery,network,internet
page.metaDescription=Learn how to optimize your app to reduce battery drain and use power-hungry resources efficiently.
page.article=true
trainingnavtop=true
startpage=true
@@ -23,12 +26,13 @@ startpage=true
</div>
<p>For your app to be a good citizen, it should seek to limit its impact on the battery life of its
host device. After this class you will be able to build apps that modify their functionality
and behavior based on the state of the host device.</p>
device. After this class you will be able to build apps that modify their functionality
and behavior based on the state of its device.</p>
<p>By taking steps such as disabling background service updates when you lose connectivity, or
reducing the rate of such updates when the battery level is low, you can ensure that the impact of
your app on battery life is minimized, without compromising the user experience.</p>
<p>By taking steps such as batching network requests, disabling background service updates when you
lose connectivity, or reducing the rate of such updates when the battery level is low, you can
ensure that the impact of your app on battery life is minimized, without compromising the user
experience.</p>
<h2>Lessons</h2>
@@ -37,6 +41,11 @@ These should be short and to the point. It should be clear from reading the summ
will want to jump to a lesson or not.-->
<dl>
<dt><b><a href="{@docRoot}training/performance/battery/network/index.html">Reducing Network Battery
Drain</a></b></dt>
<dd>Learn how to analyze your app's use of network resources and optimize it to reduce
power consumption.</dd>
<dt><b><a href="doze-standby.html">Optimizing for Doze and App Standby</a></b></dt>
<dd>Learn how to test and optimize your app for the power-management features introduced in
Android 6.0 Marshmallow.</dd>

View File

@@ -0,0 +1,100 @@
page.title=Optimizing General Network Use
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#compress-data">Compress Data</a>
<li><a href="#cache-locally">Cache Files Locally</a></li>
<li><a href="#pre-fetch">Optimize Pre-Fetch Cache Size</a></li>
</ol>
</div>
</div>
<p>
In general, reducing the amount of network traffic helps reduce battery drain.
In addition to the battery-optimization techniques of the previous lessons,
you should look at these general-purpose techniques and see if you can apply
them to your app.
</p>
<p>
This lesson briefly covers techniques that you can use to lower network traffic and
consequently reduce the battery drain caused by your app.
</p>
<h2 id="compress-data">Compress Data</h2>
<iframe width="448" height="252"
src="//www.youtube.com/embed/IwxIIUypnTE?autohide=1&amp;showinfo=0"
frameborder="0" allowfullscreen=""
style="float: right; margin: 0 0 20px 20px;"></iframe>
<p>
Reducing the amount of data sent or received over a network connection also
reduces the duration of the connection, which conserves battery. You can:
</p>
<ul>
<li>Compress data, using a compression technique such as GZIP compression.</li>
<li>Use succinct data protocols. While JSON and XML offer human-readability, and
language-flexibility, they are bandwidth-heavy formats, with
high serialization costs in the Android platform. Binary serialization formats,
such as <a href="https://developers.google.com/protocol-buffers/">Protocol Buffers</a> or
<a href="https://google.github.io/flatbuffers/">FlatBuffers</a> offer a smaller on-the-wire
packet size, as well as faster encoding and decoding time. If your application transfers a lot
of serialized data on a regular basis, these formats can yield benefits for decoding time and
transfer size.
</li>
</ul>
<h2 id="cache-locally">Cache Files Locally</h2>
<iframe width="448" height="252"
src="//www.youtube.com/embed/7lxVqqWwTb0?autohide=1&amp;showinfo=0"
frameborder="0" allowfullscreen=""
style="float: left; margin: 0 20px 20px 0;"></iframe>
<p>
Your app can avoid downloading duplicate data by caching. Always cache static resources,
including on-demand downloads such as full size images, and cache them for as long as reasonably
possible.
</p>
<p>
For example, you should consider this approach for a networked app that displays data from
user-initiated network requests as the primary content on the screen. When the user opens this
screen the first time, the app should display a splash screen. Subsequent loads should initially
load with the data that was cached from the last network request. The screen reloads with
new data once the network request is complete.
</p>
<p>
To learn about caching, watch the video. To implement caching in your app, see <a href=
"{@docRoot}training/efficient-downloads/redundant_redundant.html#LocalCache">Cache Files
Locally</a>.
</p>
<h2 id="pre-fetch">Optimize Pre-Fetch Cache Size</h2>
<p>
Optimize pre-fetch cache size based on local file system size and current network connectivity.
You can use the connectivity manager to determine what type of networks (Wi-FI, LTE, HSPAP, EDGE,
GPRS) are active and modify your pre-fetching routines to minimize battery load.
</p>
<p>
For more information, see
<a href="{@docRoot}training/efficient-downloads/connectivity_patterns.html#Bandwidth">Use
Modifying your Download Patterns Based on the Connectivity Type</a>.
</p>

View File

@@ -0,0 +1,134 @@
page.title=Optimizing App-Initiated Network Use
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#batch-schedule">Batch and Schedule Network Requests</a>
<li><a href="#check-connect">Allow System to Check for Connectivity</a></li>
</ol>
</div>
</div>
<p>
Network traffic initiated by your app can usually be significantly optimized, since you can plan
for what network resources it needs and set a schedule for accessing them. By applying careful
scheduling, you can create significant periods of rest for the device radio and, thereby, save
power. There are several Android APIs that can help with network access scheduling, and some of
these functions can coordinate network access for other apps, further optimizing battery
performance.
</p>
<p>
This lesson teaches you how to reduce battery consumption by applying techniques for
optimizing app-initiated network traffic.
</p>
<h2 id="batch-schedule">Batch and Schedule Network Requests</h2>
<iframe width="448" height="252"
src="//www.youtube.com/embed/Ecz5WDZoJok?autohide=1&amp;showinfo=0"
frameborder="0" allowfullscreen=""
style="float: right; margin: 0 0 20px 20px;"></iframe>
<p>
On a mobile device, the process of turning on the radio, making a connection, and keeping the
radio awake uses a large amount of power. For this reason, processing individual requests at
random times can consume significant power and reduce battery life. A more efficient approach is
to queue a set of network requests and process them together. This allows the system to pay the
power cost of turning on the radio just once, and still get all the data requested by an app.
</p>
<iframe width="448" height="252"
src="//www.youtube.com/embed/orlRuEwlDoM?autohide=1&amp;showinfo=0"
frameborder="0" allowfullscreen=""
style="float: left; margin: 0 20px 20px 0;"></iframe>
<p>
Using a network access scheduler API for queuing and processing your app data requests can
significantly increase the power efficiency of your app. Schedulers conserve battery power by
grouping requests together for the system to process. They can further improve efficiency by
delaying some requests until other requests wake up the mobile radio, or waiting until the
device is charging. Schedulers defer and batch network requests system-wide, across all apps on
the device, which gives them an optimizing advantage over what any individual app can do.
</p>
<h3 id="choosing-scheduler">Choosing a batch-and-scheduling API</h3>
<p>
Android provides three different APIs for your app to batch and schedule network requests. For
most operations, these techniques are functionally equivalent. These APIs are listed in the
following table with the most highly recommended first.
</p>
<table>
<tr>
<th>Scheduler</th>
<th>Requirements</th>
<th>Implementation Ease</th>
</tr>
<tr>
<td style="white-space: nowrap;"><a href="https://developers.google.com/cloud-messaging/network-manager">
GCM Network Manager</a></td>
<td>GCM Network Manager requires that your app use the Google Play services client library,
version 6.1.11 or higher &mdash; use the latest available version.</td>
<td>Straightforward</td>
</tr>
<tr>
<td><a href="{@docRoot}reference/android/app/job/JobScheduler.html">Job Scheduler</a></td>
<td>Job Scheduler does not require Google Play services, but is available only when targeting
Android 5.0 (API level 21) or higher.</td>
<td>Straightforward</td>
</tr>
<tr>
<td>
<a href="{@docRoot}training/sync-adapters/index.html">Sync Adapter for scheduled syncs</a>
</td>
<td>Sync Adapter does not require the Google Play services client library and has been
available since Android 2.0 (API level 5).</td>
<td>Complex</td>
</tr>
</table>
<p class="note">
<strong>Note:</strong> For scheduled data synchronization, you should <em>always</em> prefer GCM
Network Manager or Job Scheduler over Sync Adapter if your requirements allow it.
</p>
<h2 id="check-connect">Allow System to Check for Connectivity</h2>
<p>
One of the most serious and unexpected causes of battery drain is when a user travels beyond the
reach of any cell tower or access point. In this situation, the user is typically not using their
device, but they notice the device getting warm, and then see that the battery is low or has run
out.
</p>
<p>
In this scenario, the problem is that an app is running a background process that keeps
waking up the mobile radio at regular intervals to search for a cellular signal, but finds none.
Searching for a cell signal is one of the most power-draining operations there is.
</p>
<p>
The way to avoid causing this kind of problem for a user with your app is to use a
battery-efficient method for checking connectivity. For app-initiated network requests, use a
<a href="#choosing-scheduler">scheduler</a>, which automatically uses <a href=
"{@docRoot}training/monitoring-device-state/connectivity-monitoring.html">Connectivity
Manager</a> to check for connectivity before calling into your app. As a result, if there's no
network, the Connectivity Manager conserves battery because it performs the connectivity check
itself, without loading the app to run the check. Battery is further conserved because schedulers
use <a href="http://en.wikipedia.org/wiki/Exponential_backoff" class="external-link">exponential
backoff</a> to check for connectivity less frequently as time progresses.
</p>

View File

@@ -0,0 +1,78 @@
page.title=Optimizing Server-Initiated Network Use
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#gcm">Send Server Updates with GCM</a>
</ol>
</div>
</div>
<p>
Network traffic sent by server programs to your app can be challenging to optimize. A
solution to this problem is for your appp to periodically poll the server to check for updates.
This approach can waste network connection and power when your app starts up a device's radio,
only to receive an answer that no new data is available. A far more efficient approach would be
for the to notify your app when it has new data, but figuring out how to send a notification
from your server to potentially thousands of devices was previously no easy feat.
</p>
<p>
The <a href="https://developers.google.com/cloud-messaging/gcm">Google Cloud Messaging</a> (GCM)
service solves this communication problem by allowing your servers to send notifications to
instances of your app wherever they are installed, enabling greater network efficiency and
lowering power usage.
</p>
<p>
This lesson teaches you how to apply the GCM service to reduce network use for server-initiated
actions and reduce battery consumption.
</p>
<h2 id="gcm">Send Server Updates with GCM</h2>
<p>
Google Cloud Messaging (GCM) is a lightweight mechanism used to transmit brief messages from an
app server to your app. Using GCM, your app server uses a message-passing
mechanism to notify your app that there is new data available. This approach eliminates network
traffic that your app would perform, by not contacting a backend server for new data when no
data is available.
</p>
<p>
An example use of GCM is an app that lists speaker sessions at a conference. When sessions are
updated on your server, the server sends a brief message to your app telling it updates are
available. Your app can then call the server to update the sessions on the device only when
the server has new data.
</p>
<p>
GCM is more efficient than having your app poll for changes on the server. The GCM service
eliminates unnecessary connections where polling would return no updates, and it avoids running
periodic network requests that could cause a device's radio to power up. Since GCM can be used by
many apps, using it in your app reduces the total number of network connections needed on a
device and allows the device radio to sleep more often.
</p>
<p>
For more information about GCM and how to implement it for your app, see
<a href="https://developers.google.com/cloud-messaging/gcm">Google Cloud Messaging</a>.
</p>
<p class="note">
<strong>Note:</strong> When using GCM, your app can pass messages in normal or high priority.
Your server should typically use <a href=
"https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message">
normal priority</a> to deliver messages. Using this priority level prevents devices from being
woken up if they are inactive and in a low-power <a href=
"https://developer.android.com/training/monitoring-device-state/doze-standby.html">Doze</a>
state. Use high priority messages only if absolutely required.
</p>

View File

@@ -0,0 +1,128 @@
page.title=Optimizing User-Initiated Network Use
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#pre-fetch-data">Pre-fetch Network Data</a>
<li><a href="#check-or-listen">Check for Connectivity or Listen for Changes</a></li>
<li><a href="#reduce-connections">Reduce the Number of Connections</a></li>
</ol>
</div>
</div>
<p>
Quick handling of user requests helps ensure a good user experience, especially when it comes to
user actions that require network access. You should prioritize low latency over power
conservation to provide the fastest response when optimizing network use that is a direct result
of user actions. Attaining an optimal network traffic profile for your app, while making sure
that your users get fast responses, can be a bit challenging.
</p>
<p>
This lesson teaches you how to optimize network use for user-initiated
actions and reduce battery consumption.
</p>
<h2 id="pre-fetch-data">Pre-fetch Network Data</h2>
<iframe width="448" height="252"
src="//www.youtube.com/embed/Rk1u7VVmadE?autohide=1&amp;showinfo=0"
frameborder="0" allowfullscreen=""
style="float: right; margin: 0 0 20px 20px;"></iframe>
<p>
Pre-fetching data is an effective way to reduce the number of independent data transfer sessions
that your app runs. With pre-fetching, when the user performs an action in your app, the app
anticipates which data will most likely be needed for the next series of user actions and fetches
that data in bulk. Battery power consumption is reduced for two reasons:
<ul>
<li>
Because your app pre-fetches data only when the the mobile radio is already awake from
the user's action, and so does not incur the overhead of waking up the mobile radio.
</li>
<li>
The app pre-fetches data for anticipated user actions, each of which might otherwise
require separate requests that each incur waking up the mobile radio.
</li>
</ul>
</p>
<p class="note">
<strong>Tip:</strong> To explore whether your app might benefit from pre-fetching, review your
app's network traffic and look for situations where a specific series of user actions almost
always results in multiple network requests over the course of the task. For instance, an app
that incrementally downloads article content as a user views it might be able to pre-fetch one or
more articles in categories the user is known to view.
</p>
<p>
Watch the video on effective pre-fetching which describes what pre-fetching is, where to
use it, and how much data to pre-fetch. For more details, see <a href=
"{@docRoot}training/efficient-downloads/efficient-network-access.html#PrefetchData">Optimizing
Downloads for Efficient Network Access</a>.
</p>
<h2 id="check-or-listen">Check for Connectivity or Listen for Changes</h2>
<p>
Searching for a cell signal is one of the most power-draining operations on a mobile
device. Your app should always check for connectivity before sending a user-initiated network
request. If you use a scheduling service, <a href=
"{@docRoot}training/performance/battery/network/action-app-traffic.html#choosing-scheduler">Schedulers</a>
do this automatically for you.
</p>
<ul>
<li>If only certain buttons in your activity depend on a network connection, use <a href=
"{@docRoot}reference/android/net/ConnectivityManager.html">Connectivity Manager</a> to check for
a network connection before sending the network request, as instructed in <a href=
"{@docRoot}training/monitoring-device-state/connectivity-monitoring.html#MonitorChanges">Monitor
for Changes in Connectivity</a>. If there's no network, the app can save battery by not forcing
the mobile radio to search.
</li>
<li>If your entire activity's user interface is non-functional without network access, then use
<a href="{@docRoot}training/monitoring-device-state/manifest-receivers.html">Manipulate Broadcast
Receivers on Demand</a>. This technique listens for connectivity changes when your activity is in
the foreground, and prevents network requests from proceeding when no connectivity exists. That
is, if your app detects that connectivity has been lost, it disables all of its receivers, except
for the connectivity-change receiver. An example would be a news app that presents an activity
with a full-screen view of news snippets and does no pre-fetching. Any snippet a user taps would
require a network connection.
</li>
</ul>
<p>
A best practice for user-initiated traffic is to first check for a connection using <a href=
"{@docRoot}reference/android/net/ConnectivityManager.html">Connectivity Manager</a>, and if there
is no connection, <a href="#heading=h.a114i7ic2bxc">schedule</a> the network request for when the
connection is made. Schedulers will use techniques such as exponential backoff to save battery,
where each time the attempt to connect fails, the scheduler doubles the delay before the next
retry.
</p>
<p class="note">
<strong>Note:</strong> To check for connectivity for app-initiated traffic, see <a href=
"action-app-traffic.html#check-connect">Optimizing App-Initiated Network Use</a>.
</p>
<h2 id="reduce-connections">Reduce the Number of Connections</h2>
<p>
In general, it's more efficient to reuse existing network connections than to initiate new ones.
Reusing connections also allows the network to more intelligently react to congestion and related
network data issues. For more information on reducing the number of connections used by your app,
see <a href="{@docRoot}training/efficient-downloads/efficient-network-access.html#ReduceConnections">
Optimizing Downloads for Efficient Network Access</a>.
</p>

View File

@@ -0,0 +1,215 @@
page.title=Analyzing Network Traffic Data
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#general-traffic">Analyze App Network Traffic</a></li>
<li><a href="#traffic-types">Analyze Network Traffic Types</a></li>
</ol>
</div>
</div>
<p>
In the previous section, you tagged your app code with traffic identifiers, ran tests, and
collected data. This lesson teaches you how to look at the network traffic data you have
collected and directs you to actions for improving your app's networking performance and
reducing power consumption.
</p>
<h2 id="general-traffic">Analyze App Network Traffic</h2>
<p>
Efficient use of network resources by an app is characterized by significant periods where
the network hardware is not in use.
On mobile devices, there is a significant cost associated with starting up the radio
to send or receive data, and with keeping the mobile radio active for long periods. If your app
is accessing the network efficiently, you should see that its communications over the network are
tightly grouped together, well spaced with periods where the app is making no connection requests.
</p>
<p>
Figure 1 shows suboptimal network traffic from app, as measured by the Network Traffic tool. The
app is making frequent network requests. This traffic has few periods of
rest where the radio could switch to a standby, low-power mode. The network access behavior of
this app is likely to keep the radio on for extended periods of time, which is
battery-inefficient.
</p>
<img src="{@docRoot}images/training/performance/suboptimal_network_traffic_pattern.png"
alt="" id="figure1" />
<p class="img-caption">
<strong>Figure 1.</strong> Battery-inefficient network activity measured from an app.
</p>
<p>
Figure 2 shows an optimal network traffic pattern. The app sends network requests in bursts,
separated by long periods of no traffic where the radio can switch to standby. This chart shows
the same amount of work being done as Figure 1, but the requests have been shifted and grouped to
allow the radio to be in standby most of the time.
</p>
<img src="{@docRoot}images/training/performance/optimal_network_traffic_pattern.png"
alt="" id="figure2" />
<p class="img-caption">
<strong>Figure 2.</strong> Battery-efficient network activity measured from an app.
</p>
<p>
If the network traffic for your app looks similar to the graph in Figure 2, you are in good
shape! Congratulations! You may want to pursue further networking efficiency by checking out the
techniques described in <a href=
"{@docRoot}training/performance/battery/network/action-any-traffic.html">Optimizing General Network
Use</a>
</p>
<p>
If the network traffic for your app looks more like the graph in Figure 1, it's time to take a
harder look at how your app accesses the network. You should start by analyzing what types of
network traffic your app is generating.
</p>
<h2 id="traffic-types">Analyze Network Traffic Types</h2>
<p>
When you look at the network traffic generated by your app, you need to understand the source of
the traffic, so you can optimize it appropriately. Frequent network activity generated by your
app may be entirely appropriate if it is responding to user actions, but completely inappropriate
if you app is not in the foreground or if the device in a pocket or purse. This section discusses
how to analyze the types of network traffic being generated by your app and directs you to
actions you can take to improve performance.
</p>
<p>
In the previous lesson, you tagged your app code for different traffic types and used the Network
Traffic tool to collect data on your app and produce a graph of activity, as shown in Figure 3.
</p>
<img src="{@docRoot}images/training/performance/network_traffic_colors.png" />
<p class="img-caption">
<strong>Figure 3.</strong> Network traffic tagged for the three categories: user, app, and
server.
</p>
<p>
The Network Traffic tool colors traffic based on the tags you created in the previous lesson. The
colors are based on the traffic type <a href=
"{@docRoot}training/performance/battery/network/gather-data.html#constants">constants you defined</a> in
your app code. Refer back to your app code to confirm which constants represent user, app, or
server-initiated traffic.
</p>
<p>
The following sections discuss how to look at network traffic types and provides recommendations
on how to optimize traffic.
</p>
<h3 id="user">Analyzing user-initiated network traffic</h3>
<p>
Network activity initiated by the user may be efficiently grouped together while a user is
performing a specific activity with your app, or spread out unevenly as the user requests additional
information your app needs to get. Your goal in analyzing user-initiated network traffic is to
look for patterns of frequent network use over time and attempt to create, or increase the size
of, periods where the network is not accessed.
</p>
<p>
The unpredictability of user requests makes it challenging to optimize this type of network use
in your app. In addition, users expect fast responses when they are actively using an app, so
delaying requests for efficiency can lead to poor user experiences. In general, you should
prioritize a quick response to the user over efficient use of the network while a user is
directly interacting with your app.
</p>
<p>
Here are some approaches for optimizing user-initiated network traffic:
</p>
<ul>
<li>
<a href="{@docRoot}training/performance/battery/network/action-user-traffic.html#pre-fetch-data">
Pre-fetch Network Data</a> - When the user performs an action in your app, the app
anticipates which data may be needed for the next user actions, fetches it in bulk
in a single connection, and holds it until the user requests it.
</li>
<li>
<a href="{@docRoot}training/performance/battery/network/action-user-traffic.html#check-or-listen">
Check for Connectivity or Listen for Changes</a> - Check for network connectivity or listen
for connectivity changes before performing an update.
</li>
<li>
<a href="{@docRoot}training/performance/battery/network/action-user-traffic.html#reduce-connections">
Reduce the Number of Connections</a> - Use server APIs that allow data to be downloaded in sets.
</li>
</ul>
<p class="caution">
<strong>Caution:</strong> Beware of network activity grouping bias in your user activity test
data! If you ran a set of user scenarios with your network testing plan, the graph of
user-initiated network access may be unrealistically grouped together, potentially causing you to
optimize for user behavior that does not actually occur. Make sure your user network test
scenarios reflect realistic use of your app.
</p>
<h3 id="app">Analyzing app-initiated network traffic</h3>
<p>
Network activity initiated by your app code is typically an area where you can have a significant
impact on the efficient use of network bandwidth. In analyzing the network activity of your app,
look for periods of inactivity and determine if they can be increased. If you see patterns of
consistent network access from your app, look for ways to space out these accesses to allow the
device radio to switch into low power mode.
</p>
<p>
Here are some approaches for optimizing app-initiated network traffic:
</p>
<ul>
<li>
<a href="{@docRoot}training/performance/battery/network/action-app-traffic.html#batch-schedule">
Batch and Schedule Network Requests</a> - Defer your app's network requests so they can be
processed together and at a time which is advantageous for battery life.
</li>
<li>
<a href="{@docRoot}training/performance/battery/network/action-app-traffic.html#check-connect">
Allow System to Check for Connectivity</a> - Avoid the battery cost of running your app just
to check for a network connection when you can let the system run the check while your app
sleeps.
</li>
</ul>
<h3 id="server">Analyzing server-initiated network traffic</h3>
<p>
Network activity initiated by servers communicating with your app is also typically an area where
you can have a significant impact on the efficient use of network bandwidth. In analyzing the
network activity from server connections, look for periods of inactivity and determine if they
can be increased. If you see patterns of consistent network activity from servers, look for ways
to space out this activity to allow the device radio to switch into low power mode.
</p>
<p>
Here is an approach for optimizing app-initiated network traffic:
</p>
<ul>
<li>
<a href="action-server-traffic.html#gcm">Use GCM for Server Updates</a> - Consider using
the Google Cloud Messaging service for server side updates instead of polling.
</li>
</ul>

View File

@@ -0,0 +1,267 @@
page.title=Collecting Network Traffic Data
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to </h2>
<ol>
<li><a href="#tag-requests">Tag Network Requests</a></li>
<li><a href="#build-type">Configure a Network Test Build Type</a></li>
<li><a href="#deploy-apk">Deploy the Network Test APK</a></li>
<li><a href="#network-tool">Run Network Traffic Tool</a></li>
</ol>
</div>
</div>
<p>
The network traffic generated by an app can have a significant impact on the battery life of the
device where it is running. In order to optimize that traffic, you need to both measure it and
identify its source. Network requests can come directly from a user action, requests from your own
app code, or from a server communicating with your app.
</p>
<p>
The <a href="{@docRoot}tools/debugging/ddms.html#network">Network Traffic tool</a> (part of the
DDMS tools) enables you to view how and when your app transfers data over a network.
</p>
<p>
This lesson shows you how to measure and categorize network requests by tagging your source code,
then shows you how to deploy, test and visualize your apps's network traffic.
</p>
<h2 id="tag-requests">Tag Network Requests</h2>
<p>
Apps use the networking hardware on a device for various reasons. In order to properly optimize
your app's use of networking resources, you must understand how frequently your app is using the
network and for what reasons. For performance analysis purposes, you should break down use of
network hardware into these categories:
</p>
<ul>
<li>
<strong>User-initiated network requests</strong> - Requests initiated by the user, such as a
user request for an updated articles list in a news app.
</li>
<li>
<strong>App-initiated network requests</strong> - Requests initiated within Android app code
that are not used to immediately satisfy a user action, such as an app request to cache the
text of unread articles in a news app.
</li>
<li>
<strong>Server-initiated network requests</strong> - Requests initiated by a server to your app
that are not used to immediately satisfy a user action, such as notification of a newly
available article in a news app.
</li>
</ul>
<p>
This procedure shows you how to tag your app's source code with constants to categorize traffic
as one of these three request types. The Network Traffic tool represents each type of traffic
with a different color, so you can visualize and optimize each traffic stream separately.
The technique described here reports network traffic based on the execution of threads in your
app which you identify as a user, app or server source.
</p>
<ol>
<li>In your app's development project, define three constants to represent the different types
of network use:
<pre id="constants">
public static final int USER_INITIATED = 0x1000;
public static final int APP_INITIATED = 0x2000;
public static final int SERVER_INITIATED =0x3000;
</pre>
</li>
<li>Find networking code in your app by searching for the most common classes used for
this purpose:
<ol type="a">
<li>In Android Studio, choose <strong>Edit &gt; Find &gt; Find in Path</strong>.</li>
<li>Paste the following string into the <strong>Text to find</strong> field:<br>
<code>extends GcmTaskService|extends JobService|extends
AbstractThreadedSyncAdapter|HttpUrlConnection|Volley|Glide|HttpClient</code>
</li>
<li>Check <strong>Regular expression</strong>.</li>
<li>Check <strong>File mask(s)</strong> and type <code>*.java</code>.</li>
<li>Click the <strong>Find</strong> button.</li>
</ol>
</li>
<li>
Based on your findings in the previous step, tag your app's use of network traffic by adding the
{@link android.net.TrafficStats#setThreadStatsTag} method to each execution thread in your app
that uses network resources, as shown in the following code example.
<pre>
if (BuildConfig.NETWORK-TEST && Build.VERSION.SDK_INT &gt;= 14) {
try {
TrafficStats.setThreadStatsTag(USER_INITIATED);
// make network request using HttpClient.execute()
} finally {
TrafficStats.clearThreadStatsTag();
}
}
</pre>
<p class="note">
<strong>Note:</strong> Ensure the tagging does not get into your production code by making
inclusion of this code conditional, based on the build type used to generate the APK.
In the example above, the <code>BuildConfig.NETWORK-TEST</code> field identifies this
APK as a test version.
</p>
</li>
</ol>
<p class="note">
<strong>Note:</strong> This technique for tagging network traffic from your app depends on
how the APIs that you are using access and manage network sockets. Some networking libraries
may not allow the {@link android.net.TrafficStats} utilities to tag traffic from your app.
</p>
<p>
For more information about tagging and tracking network traffic with the Network Traffic tool,
see <a href="http://tools.android.com/recent/detailednetworkusageinddms">Detailed Network Usage
in DDMS</a>.
</p>
<h2 id="build-type">Configure a Network Test Build Type</h2>
<p>
When you run performance tests, your APK should be as close as possible to the production
build. In order to achieve this for your network testing, create a <code>network-test</code>
build type, rather than using <code>debug</code> build type.
</p>
<ol>
<li>Open your app in Android Studio.</li>
<li>Create a debuggable build type for your network test by modifying your project's
<code>build.gradle</code> file as shown in the following code example:
<pre>
android {
...
buildTypes {
debug {
// debuggable true is default for the debug buildType
}
<strong>network-test {
debuggable true
}</strong>
}
...
}
</pre>
</li>
</ol>
<h2 id="deploy-apk">Deploy the Network Test APK</h2>
<p>
To deploy the APK generated by the {@code network-test} build type configured in the previous
proceedure:
</p>
<ol>
<li>Check that <strong>Developer Options</strong> are enabled on your test device. For
information about how to check and enable this option, see <a href=
"{@docRoot}tools/device.html#developer-device-options">Using Hardware Devices</a>.
</li>
<li>Using a USB cable, connect your test device to your development computer.
</li>
<li>In Android Studio, select <strong>Build Variants</strong> on the left edge of the window.
</li>
<li>Click the <strong>Sync Project with Gradle Files</strong> button to populate the
Build Variants list with <code>network-test</code> for the app module.
</li>
<li>Choose <code>network-test</code> from the list.
</li>
<li>Deploy the debuggable version of your app to your device by choosing
<strong>Run</strong> &gt; <strong>Debug</strong>.
</li>
</ol>
<h2 id="network-tool">Run Network Traffic Tool</h2>
<p>
The Network Traffic tool in Android Studio helps you see how your app uses network resources
in real time, while it is running.
</p>
<p>
To improve the repeatability of your testing, you should start with a known initial state for
your app by clearing app data. The following procedure includes a step that shows you how to
clear <em>all</em> app data including previously cached data and networking data. This step
puts your app back to a state where it must re-cache all previously cached data. Do not skip
this step.
</p>
<p>
To start the Network Traffic tool and visualize the network requests:
</p>
<ol>
<li>Start the Network Traffic tool by launching Android Studio and choosing <strong>Tools &gt;
Android &gt; Android Device Monitor</strong>. When asked, allow incoming network connections.
</li>
<li>In the Android Device Monitor window, click the <strong>DDMS</strong> button along the top
and choose the <strong>Network Statistics</strong> tab. If you don't see this tab, widen the
window and then try <strong>Window &gt; Reset Perspective</strong>.
</li>
<li>Select your app to debug from the list of debuggable apps on your device in the
<strong>Devices</strong> tab, then click the <strong>Start</strong> button in the
<strong>Network Statistics</strong> tab.
<p class="note">
<strong>Note:</strong> You may be prompted to <strong>Allow USB Debugging</strong> on your
device. Select <strong>OK</strong> to allow debugging to proceed.
</p>
</li>
<li>Clear your app data using the following adb command:
<pre class="no-pretty-print">
adb shell pm clear <em>package.name.of.app</em>
</pre>
</li>
<li>Start your app and run a testing plan that exercises your app's primary use cases. Your plan
should also allow for app idle time, where the user is not interacting with the app, to allow
app-initiated and server-initiated network access to occur.
</li>
<li>Repeat the test by clearing the app data and running your test plan again. You should repeat
the test a few times to verify the repeatability of your performance data.
</li>
</ul>
</ol>
<p>
Use of tagging for network traffic helps you visually distinguish each request category by
producing a different color for each network traffic in the Network Traffic tool, as shown in
Figure 1.
</p>
<img src="{@docRoot}images/training/performance/network_traffic_colors.png" />
<p class="img-caption">
<strong>Figure 1.</strong> Network traffic tagged for the three categories.
</p>

View File

@@ -0,0 +1,86 @@
page.title=Reducing Network Battery Drain
page.article=true
page.tags=battery
page.metaDescription=Learn how to optimize your app to reduce battery drain and use network resources efficiently.
@jd:body
<iframe width="448" height="252"
src="//www.youtube.com/embed/fEEulSk1kNY?autohide=1&amp;showinfo=0"
frameborder="0" allowfullscreen=""
style="float: right; margin: 0 0 20px 20px;"></iframe>
<p>
Requests that your app makes to the network are a major cause of battery drain because they turn
on the power-hungry mobile or Wi-Fi radios. Beyond the power needed to send and receive packets,
these radios expend extra power just turning on and keeping awake. Something as simple as a
network request every 15 seconds can keep the mobile radio on continuously and quickly use up
battery power.
</p>
<p>
This lesson shows you how to tag your app's source code to categorize, visualize and color
your network requests according to how they are initiated. From there, each category
identifies areas of your app that you can make more battery-efficient.
</p>
<h2>Performance Actions</h2>
<dl>
<dt>
<strong><a href="gather-data.html">
Collecting Network Traffic Data</a></strong>
</dt>
<dd>
Learn how to instrument your app's code and gather data on its use of network resources.
</dd>
<dt>
<strong><a href="analyze-data.html">
Analyzing Network Traffic Data</a></strong>
</dt>
<dd>
Learn how to analyze your app's use of network resources in response to user actions
and optimize it to reduce power consumption.
</dd>
<dt>
<strong><a href="action-user-traffic.html">
Optimizing User-Initiated Network Use</a></strong>
</dt>
<dd>
Learn how to optimize your app's use of network resources in response to user actions
to reduce power consumption.
</dd>
<dt>
<strong><a href="action-app-traffic.html">
Optimizing App-Initiated Network Use</a></strong>
</dt>
<dd>
Learn how to optimize your app's requests for network resources to reduce
power consumption.
</dd>
<dt>
<strong><a href="action-server-traffic.html">
Optimizing Server-Initiated Network Use</a></strong>
</dt>
<dd>
Learn how to optimize your app's requests for network resources and to reduce
power consumption.
</dd>
<dt>
<strong><a href="action-any-traffic.html">
Optimizing General Network Use</a></strong>
</dt>
<dd>
Learn how to optimize your app's requests for network resources and to reduce
power consumption.
</dd>
</dl>

View File

@@ -1889,6 +1889,7 @@ results."
</li>
</ul>
</li>
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/monitoring-device-state/index.html"
@@ -1902,7 +1903,42 @@ results."
</a>
</div>
<ul>
<li><a href="<?cs var:toroot ?>training/monitoring-device-state/doze-standby.html"
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/app/battery/network/index.html">
Reducing Network Battery Drain
</a>
</div>
<ul>
<li><a href="<?cs var:toroot ?>training/app/battery/network/gather-data.html">
Collecting Network Traffic Data
</a>
</li>
<li><a href="<?cs var:toroot ?>training/app/battery/network/analyze-data.html">
Analyzing Network Traffic Data
</a>
</li>
<li><a href="<?cs var:toroot ?>training/app/battery/network/action-user-traffic.html">
Optimizing User-Initiated Network Use
</a>
</li>
<li><a href="<?cs var:toroot ?>training/app/battery/network/action-app-traffic.html">
Optimizing App-Initiated Network Use
</a>
</li>
<li><a href="<?cs var:toroot ?>training/app/battery/network/action-server-traffic.html">
Optimizing Server-Initiated Network Use
</a>
</li>
<li><a href="<?cs var:toroot ?>training/app/battery/network/action-any-traffic.html">
Optimizing General Network Use
</a>
</li>
</ul>
</li> <!-- End of Reducing Network Battery Drain -->
<li><a href="<?cs var:toroot ?>training/monitoring-device-state/doze-standby.html"
>Optimizing for Doze and App Standby</a>
</li>
<li><a href="<?cs var:toroot ?>training/monitoring-device-state/battery-monitoring.html"