• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Building for Billions
2page.metaDescription=Best practices on how to optimize Android apps for low- and no-bandwidth and low-cost devices.
3page.image=/distribute/images/billions-guidelines.png
4
5@jd:body
6
7<!-- table of contents -->
8<div id="qv-wrapper"><div id="qv">
9<h2><a href="#connectivity">Connectivity</a></h2>
10 <ol>
11  <li><a href="#images">Optimize images</a></li>
12  <li><a href="#network">Optimize networking</a></li>
13  <li><a href="#transfer">Fine-tune data transfer</a></li>
14 </ol>
15<h2><a href="#capability">Device Capability</a></h2>
16 <ol>
17  <li><a href="#screens">Support varying screen sizes</a></li>
18  <li><a href="#compatibility">Backward compatibility</a></li>
19  <li><a href="#memory">Efficient memory usage</a></li>
20 </ol>
21
22<h2><a href="#cost">Data Cost</a></h2>
23 <ol>
24  <li><a href="#appsize">Reduce app size</a></li>
25  <li><a href="#configurablenetwork">Offer configurable network usage</a></li>
26 </ol>
27
28<h2><a href="#consumption">Battery Consumption</a></h2>
29 <ol>
30  <li><a href="#consumption-reduce">Reduce battery consumption</a></li>
31  <li><a href="#consumption-benchmark">Benchmark battery usage</a></li>
32 </ol>
33
34<h2><a href="#contentsection">Content</a></h2>
35 <ol>
36  <li><a href="#content-responsive">Fast and responsive UI</a></li>
37  <li><a href="#ui">UI Best practices</a></li>
38  <li><a href="#localization">Localization</a></li>
39 </ol>
40</div>
41</div>
42
43<!-- intro -->
44<p>Internet use—and smartphone penetration—is growing fastest in markets with
45 low, intermittent, or expensive connectivity. Successful apps in these
46 markets need to perform across a variety of speeds and devices, as well as
47 conserve and share information about battery and data consumption.</p>
48
49<p>To help you address these important considerations, we’ve compiled the
50 following checklist. These do not follow a particular order, and as
51 always it's a good idea to research particularities of any market or country
52 you're targeting.
53</p>
54
55<!-- connectivity -->
56<div class="headerLine">
57  <h2 id="connectivity">Connectivity</h2>
58</div>
59
60<p>Over half of the users in the world still experience your app over 2G
61 connections. To improve their experience, optimize for no- and low-connection
62 speeds. For offline and slow connections: store data, queue requests, and handle
63 images for optimal performance.
64</p>
65
66<h3 id="images">Optimize images</h3>
67<h4 id="images-format">Serve WebP images</h4>
68 <ul>
69  <li>Serve <a
70   href="https://developers.google.com/speed/webp/">WebP</a> files over the
71   network. WebP reduces image load times, saves network bandwidth, and often
72   results in smaller file sizes than its PNG and JPG counterparts, with at
73   least the same image quality. Even at lossy settings, WebP can produce a
74   nearly identical image. Android has had lossy <a
75   href="{@docRoot}guide/appendix/media-formats.html">WebP support</a> since
76   Android 4.0 (API level 14: Ice Cream Sandwich) and support for lossless /
77   transparent WebP since Android 4.2 (API level 17: Jelly Bean).</li>
78 </ul>
79<h4 id="images-sizing">Dynamic image sizing</h4>
80 <ul>
81  <li>Have your apps request images at the targeted rendering size, and have
82   your server provide those images to fit; the target rendering size will
83   vary based on device specifications. Doing this minimizes the network
84   overhead and reduces the amount of memory needed to hold each image,
85   resulting in improved performance and user satisfaction.</li>
86  <li>Your user experience degrades when users are waiting for images to
87   download. Using appropriate image sizes helps to address these issues.
88   Consider making image size requests based on network type or network
89   quality; this size could be smaller than the target rendering size.</li>
90  <li>Dynamic placeholders like <a
91   href="{@docRoot}reference/android/support/v7/graphics/Palette.html">
92   pre-computed palette values</a> or low-resolution thumbnails can improve
93   the user experience while the image is being fetched.</li>
94 </ul>
95<h4 id="images-libraries">Use image loading libraries</h4>
96 <ul>
97  <li>Your app should not have to fetch any image more than once. Image
98   loading libraries such as <a class="external-link"
99   href="https://github.com/bumptech/glide">Glide</a> and  <a
100   class="external-link" href="http://square.github.io/picasso/">Picasso</a>
101   fetch the image, cache it, and provide hooks into your Views to show
102   placeholder images until the actual images are ready. Because images are
103   cached, these libraries return the local copy the next time they are
104   requested.</li>
105  <li>Image-loading libraries manage their cache, holding onto the most recent
106   images so that your app storage doesn’t grow indefinitely.</li>
107 </ul>
108
109<h3 id="network">Optimize networking</h3>
110<h4 id="network-offline">Make your app usable offline</h4>
111 <ul>
112  <li>In places like subways, planes, elevators, and parking garages, it is
113   common for devices to lose network connectivity. Creating a useful offline
114   state results in users being able to interact with the app at all times, by
115   presenting cached information. Ensure that your app is usable offline or
116   when network connectivity is poor by storing data locally, caching data,
117   and queuing outbound requests for when connectivity is restored.</li>
118  <li>Where possible, apps should not notify users that connectivity has
119   been lost. It is only when the user performs an operation where connectivity
120   is essential that the user needs to be notified.</li>
121  <li>When a device lacks connectivity, your app should batch up network
122   requests&mdash;on behalf of the user&mdash;that can be executed when
123   connectivity is restored. An example of this is an email client that allows
124   users to compose, send, read, move, and delete existing mails even when the
125   device is offline. These operations can be cached and executed when
126   connectivity is restored. In doing so, the app is able to provide a similar
127   user experience whether the device is online or offline.</li>
128 </ul>
129<h4 id="network-arch">Use GcmNetworkManager and/or Content Providers</h4>
130 <ul>
131  <li>Ensure that your app stores all data on disk via a database or similar
132   structure so that it performs optimally regardless of network conditions
133   (for example, via SQLite + ContentProvider). The <a
134   href="https://developers.google.com/cloud-messaging/network-manager">
135   GCM Network Manager</a>
136   (<a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
137   <code>GcmNetworkManager</code></a>) can result in a robust mechanism to
138   sync data with servers while <a
139   href="{@docRoot}guide/topics/providers/content-providers.html">content
140   providers</a> ({@link android.content.ContentProvider}) cache that data,
141   combining to provide an architecture that enables a useful offline state.</li>
142  <li>Apps should cache content that is fetched from the network. Before making
143   subsequent requests, apps should display locally cached data. This ensures
144   that the app is functional regardless of whether the device is offline or
145   on a slow/unreliable network.</li>
146 </ul>
147<h4 id="network-duplicate">Deduplicate network requests</h4>
148 <ul>
149  <li>An offline-first architecture initially tries to fetch data from local
150   storage and, failing that, requests the data from the network. After being
151   retrieved from the network, the data is cached locally for future
152   retrieval. This helps to ensure that network requests for the same piece of
153   data only occur once—the rest of the requests are satisfied locally. To
154   achieve this, use a local database for long-lived data (usually
155   {@link android.database.sqlite} or
156   {@link android.content.SharedPreferences}).</li>
157  <li>An offline-first architecture always looks for data locally first, then
158   makes the request over the network. The response is cached and then returned
159   locally. Such an architecture simplifies an app’s flow between offline and
160   online states as one side fetches from the network to the cache, while the
161   other retrieves data from the cache to present to the user.</li>
162  <li>For transitory data, use a bounded disk cache such as a <a class="external-link"
163   href="https://github.com/JakeWharton/DiskLruCache"><code>DiskLruCache</code>
164   </a>. Data that doesn’t typically change should only be requested once over
165   the network and cached for future use. Examples of such data are images and
166   non-temporal documents like news articles or social posts.</li>
167 </ul>
168
169<h3 id="transfer">Fine-tune data transfer</h3>
170<h4 id="transfer-prioritize">Prioritize bandwidth</h4>
171 <ul>
172  <li>Writers of apps should not assume that any network that the device is
173   connected to is long-lasting or reliable. For this reason, apps should
174   prioritize network requests to display the most useful information to the
175   user as soon as possible.</li>
176  <li>Presenting users with visible and relevant information immediately is a
177   better user experience than making them wait for information that might not
178   be necessary. This reduces the time that the user has to wait and
179   increases the usefulness of the app on slow networks.</li>
180  <li>To achieve this, sequence your network requests such that text is
181   fetched before rich media. Text requests tend to be smaller, compress
182   better, and hence transfer faster, meaning that your app can display useful
183   content quickly. For more information on managing network requests, visit
184   the Android training on <a
185   href="{@docRoot}training/basics/network-ops/managing.html">Managing Network
186   Usage</a>.</li>
187 </ul>
188<h4 id="network-bandwidth">Use less bandwidth on slower connections</h4>
189 <ul>
190  <li>The ability for your app to transfer data in a timely fashion is
191   dependent on the network connection. Detecting the quality of the network
192   and adjusting the way your app uses it can help provide an excellent user
193   experience.</li>
194  <li>You can use the following methods to detect the underlying network
195   quality. Using the data from these methods, your app should tailor its use
196   of the network to continue to provide a timely response to user actions:
197    <ul>
198     <li>{@link android.net.ConnectivityManager}>
199     {@link android.net.ConnectivityManager#isActiveNetworkMetered}</li>
200     <li>{@link android.net.ConnectivityManager}>
201     {@link android.net.ConnectivityManager#getActiveNetworkInfo}</li>
202     <li>{@link android.net.ConnectivityManager}>
203     {@link android.net.ConnectivityManager#getNetworkCapabilities}</li>
204     <li>{@link android.telephony.TelephonyManager}>
205     {@link android.telephony.TelephonyManager#getNetworkType}</li>
206    </ul>
207  </li>
208  <li>On slower connections, consider downloading only lower-resolution media
209   or perhaps none at all. This ensures that your users are still able to use
210   the app on slow connections. Where you don’t have an image or the image is
211   still loading, you should always show a placeholder. You can create a
212   dynamic placeholder by using the <a
213   href="{@docRoot}tools/support-library/features.html#v7-palette">
214   Palette library</a> to generate placeholder colors that match the target
215   image.</li>
216  <li>Prioritize network requests such that text is fetched before rich media.
217   Text requests tend to be smaller, compress better, and hence transfer
218   faster, meaning that your app can display useful content quickly. For more
219   information on adjusting bandwidth based on network connection, see the
220   Android training on <a
221   href="{@docRoot}training/basics/network-ops/managing.html">Managing Network
222   Usage</a>.</li>
223  <li>On devices powered by Android 7.0 (API level 24) and higher,
224  users can turn on the
225  <strong>Data Saver</strong> setting, which helps minimize data usage. Android 7.0
226  extends {@link android.net.ConnectivityManager} to detect <strong>Data Saver</strong>
227  settings. For more information about this feature, see
228  <a href="/training/basics/network-ops/data-saver.html">Data Saver.</a>
229  </li>
230 </ul>
231<h4 id="network-behavior">Detect network changes, then change app behavior</h4>
232 <ul>
233  <li>Network quality is not static; it changes based on location, network
234   traffic, and local population density. Apps should detect changes in
235   network and adjust bandwidth accordingly. By doing so, your app can tailor
236   the user experience to the network quality. Detect network state using
237   these methods:
238    <ul>
239     <li>{@link android.net.ConnectivityManager}>
240     {@link android.net.ConnectivityManager#getActiveNetworkInfo}</li>
241     <li>{@link android.net.ConnectivityManager}>
242     {@link android.net.ConnectivityManager#getNetworkCapabilities}</li>
243     <li>{@link android.telephony.TelephonyManager}>
244     {@link android.telephony.TelephonyManager#getDataState}</li>
245    </ul>
246  </li>
247  <li>As the network quality degrades, scale down the number and size of
248   requests. As the connection quality improves, you can scale up your
249   requests to optimal levels.</li>
250  <li>On higher quality, unmetered networks, consider <a
251   href="{@docRoot}training/efficient-downloads/efficient-network-access.html#PrefetchData">
252   prefetching data</a> to make it available ahead of time. From a user
253   experience standpoint, this might mean that news reader apps only fetch
254   three articles at a time on 2G but fetch twenty articles at a time on
255   Wi-Fi. For more information on adjusting app behavior based on network changes,
256   visit the Android training on <a
257   href="{@docRoot}training/monitoring-device-state/connectivity-monitoring.html">
258   Monitoring the Connectivity Status</a>.</li>
259  <li>The broadcast <a
260   href="{@docRoot}reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION">
261   <code>CONNECTIVITY_CHANGE</code></a> is sent when a change in network
262   connectivity occurs. When your app is in the foreground, you can call <a
263   href="{@docRoot}reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter)">
264   <code>registerReceiver</code></a> to receive this broadcast. After receiving
265   the broadcast, you should reevaluate the current network state and adjust
266   your UI and network usage appropriately. You should not declare this receiver
267   in your manifest, as that feature is unavailable in Android 7.0 (API level 24)
268   and higher.
269   For more information about this and other changes in Android 7.0,
270   see <a href="/about/versions/nougat/android-7.0-changes.html">
271   Android 7.0 Changes</a>.</li>
272 </ul>
273
274<h3 class="rel-resources clearfloat">Related resources</h3>
275<div class="resource-widget resource-flow-layout col-13"
276  data-query="collection:distribute/essentials/billionsquality/connectivity"
277  data-sortOrder="-timestamp"
278  data-cardSizes="6x3"
279  data-maxResults="6"></div>
280
281<!-- capability -->
282<div class="headerLine">
283  <h2 id="capability">Device Capability</h2>
284</div>
285<p>Reaching new users means supporting an increasing variety of Android
286 platform versions and device specifications. Optimize for common RAM and
287 screen sizes and resolutions to improve the user experience. </p>
288
289<h3 id="screens">Support varying screen sizes</h3>
290<h4 id="screens-dp">Use density-independent pixels (dp)</h4>
291 <ul>
292  <li>Defining layout dimensions with pixels is a problem because different
293   screens have different pixel densities, so the same number of pixels may
294   correspond to different physical sizes on different devices. The
295   density-independent pixel (dp) corresponds to the physical size of a pixel
296   at 160 dots per inch (mdpi density).</li>
297  <li>Defining layouts with dp ensures that the physical size of your user
298   interface is consistent regardless of device. Visit the Android
299   guide on <a
300   href="https://developer.android.com/guide/practices/screens_support.html">
301   Supporting Multiple Screens</a> for best practices using
302   density-independent pixels.</li>
303 </ul>
304<h4 id="screens-density">Test graphics on ldpi/mdpi screen densities</h4>
305 <ul>
306  <li>Ensure that your app layouts work well on low- and medium-density
307   (ldpi/mdpi) screens because these are <a
308   href="https://developer.android.com/about/dashboards/index.html#Screens">
309   common densities</a>, especially in lower-cost devices. Testing on
310   lower-density screens helps to validate that your layouts are legible on
311   lower-density screens.</li>
312  <li>Lower-density screens can result in unclear text where the finer details
313   aren't visible. The Material Design guidelines describe <a
314   class="external-link" href="https://www.google.com/design/spec/layout/metrics-keylines.html">
315   metrics and keylines</a> to ensure that your layouts can scale across
316   screen densities.</li>
317  <li>Devices with lower-density screens tend to have lower hardware
318   specifications. To ensure that your app performs well on these devices,
319   consider reducing or eliminating heavy loads, such as animations and
320   transitions. For more information on supporting different densities, see
321   the Android training on <a
322   href="https://developer.android.com/training/multiscreen/screendensities.html">
323   Supporting Different Densities</a>.</li>
324 </ul>
325<h4 id="screens-sizes">Test layouts on small/medium screen sizes</h4>
326 <ul>
327  <li>Validate that your layouts scale down by testing on smaller screens. As
328   screen sizes shrink, be very selective about visible UI elements, because
329   there is limited space for them.</li>
330  <li>Devices with smaller screens tend to have lower hardware specifications.
331   To ensure that your app performs well on these devices, try reducing or
332   eliminating heavy loads, such as animations or transitions. For more
333   information on supporting different screen sizes, see the Android
334   training on <a
335   href="https://developer.android.com/training/multiscreen/screendensities.html">
336   Supporting Different Screen Sizes</a>.</li>
337 </ul>
338
339<h3 id="compatibility">Backward compatibility</h3>
340<h4 id="compatibility-sdkversion">Set your targetSdkVersion and minSdkVersion
341 appropriately</h4>
342 <ul>
343  <li>Apps should build and target a recent version of Android to ensure most
344   current behavior across a broad range of devices; this still provides
345   backward compatibility to older versions. Here are the best practices for
346   targeting API levels appropriately:
347    <ul>
348     <li><a
349      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">
350      {@code targetSdkVersion}</a> should be the latest version of Android.
351      Targeting the most recent version ensures that your app inherits newer
352      runtime behaviors when running newer versions of Android. Be sure to
353      test your app on newer Android versions when updating the
354      targetSdkVersion as it can affect app behavior.</li>
355     <li><a
356      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">
357      {@code minSdkVersion}</a> sets the minimum supported Android version.
358      Use Android 4.0 (API level 14: Ice Cream Sandwich) or Android 4.1 (API
359      level 16: Jelly Bean)—these versions give maximum coverage for modern
360      devices. Setting {@code minSdkVersion} also results in the Android build
361      tools reporting incorrect use of new APIs that might not be available in
362      older versions of the platform. By doing so, developers are protected
363      from inadvertently breaking backward compatibility.</li>
364    </ul>
365  </li>
366  <li>Consult the <a
367   href="https://developer.android.com/about/dashboards/index.html#Platform">
368   Android dashboards</a>, the <a class="external-link"
369   href="https://play.google.com/apps/publish/">Google Play Developer
370   Console</a> for your app, and industry research in your target markets to
371   gauge which versions of Android to target, based on your target users.</li>
372 </ul>
373<h4 id="compatibility-libraries">Use the Android Support libraries</h4>
374 <ul>
375  <li>Ensure your app provides a consistent experience across OS versions by
376   using the Google-provided support libraries such as AppCompat and the Design
377    Support Library. The Android Support Library package is a set of code
378    libraries that provides backward-compatible versions of Android framework
379    APIs as well as features that are only available through the library APIs.
380    </li>
381  <li>Some of the the highlights include:
382  <ul>
383   <li>v4 & v7 support library: Many framework APIs for older versions of
384    Android such as {@link android.support.v4.view.ViewPager},
385    {@link android.app.ActionBar},
386    {@link android.support.v7.widget.RecyclerView}, and
387    {@link android.support.v7.graphics.Palette}.</li>
388   <li><a href="{@docRoot}tools/support-library/features.html#design">Design
389    Support</a> library: APIs to support adding Material Design components
390    and patterns to your apps.</li>
391   <li><a href="{@docRoot}tools/support-library/features.html#multidex">
392    Multidex Support</a> library: provides support for large apps that have
393    more than 65K methods. This can happen if your app is using many
394    libraries.</li>
395  </ul>
396  </li>
397  <li>For more information on the available support libraries, see the <a
398   href="https://developer.android.com/tools/support-library/features.html">
399   Support Libraries Features</a> section of the Android Developer site.</li>
400 </ul>
401<h4 id="compatibility-playservices">Use Google Play services</h4>
402 <ul>
403  <li>Google Play services brings the best of Google APIs independent of
404   Android platform version. Consider using features from Google Play services
405   to offer the most streamlined Google experience on Android devices.</li>
406  <li>Google Play services also include useful APIs such as <a
407   href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
408   <code>GcmNetworkManager</code></a>, which provides much of Android 5.0’s
409   {@link android.app.job.JobScheduler} API for older versions of Android. </li>
410  <li>Updates to Google Play services are distributed automatically by the
411   Google Play Store, and new versions of the client library are delivered
412   through the Android SDK Manager. </li>
413 </ul>
414<h3 id="memory">Efficient memory usage</h3>
415<h4 id="memory-footprint">Reduce memory footprint on low-cost devices</h4>
416 <ul>
417  <li>Adjusting your memory footprint dynamically helps to ensure compatibility
418   across devices with different RAM configurations.</li>
419  <li>Methods such as {@link android.app.ActivityManager#isLowRamDevice} and
420   {@link android.app.ActivityManager#getMemoryClass()} help determine memory
421   constraints at runtime. Based on this information, you can scale down your
422   memory usage. As an example, you can use lower resolution images on low memory
423   devices.</li>
424  <li>For more information on managing your app’s memory, see the Android
425   training on <a href="{@docRoot}training/articles/memory.html">Managing
426   Your App's Memory</a>.</li>
427 </ul>
428<h4 id="memory-longprocesses">Avoid long-running processes</h4>
429 <ul>
430  <li>Long-running processes stay resident in memory and can result in slowing
431   down the device. In most situations, your app should wake up for a given
432   event, process data, and shut down. You should use <a
433   href="https://developers.google.com/cloud-messaging">Google Cloud Messaging
434   (GCM)</a> and/or <a
435   href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
436   <code>GcmNetworkManager</code></a> to avoid long running background
437   services and reduce memory pressure on the user’s device.</li>
438 </ul>
439<h4 id="memory-benchmark">Benchmark memory usage</h4>
440 <ul>
441  <li>Android Studio provides memory benchmarking and profiling tools, enabling
442   you to measure memory usage at run time. Benchmarking your app’s memory
443    footprint enables you to monitor memory usage over multiple versions of
444    the app. This can help catch unintentional memory footprint growth. These
445    tools can be used in the following ways:
446  <ul>
447   <li>Use the <a
448    href="{@docRoot}tools/performance/memory-monitor/index.html">Memory
449    Monitor</a> tool to find out whether undesirable garbage collection (GC)
450    event patterns might be causing performance problems.</li>
451   <li>Run <a
452    href="{@docRoot}tools/performance/heap-viewer/index.html">Heap Viewer</a>
453    to identify object types that get or stay allocated unexpectedly or
454    unnecessarily.</li>
455   <li>Use <a
456   href="{@docRoot}tools/performance/allocation-tracker/index.html">
457   Allocation Tracker</a> to identify where in your code the problem might
458   be.</li>
459  </ul>
460  </li>
461  <li>For more information on benchmarking memory usage, see the <a
462   href="{@docRoot}tools/performance/comparison.html">
463   Memory Profilers</a> tools on the Android Developers site.</li>
464 </ul>
465
466<h3 class="rel-resources clearfloat">Related resources</h3>
467<div class="resource-widget resource-flow-layout col-13"
468  data-query="collection:distribute/essentials/billionsquality/capability"
469  data-sortOrder="-timestamp"
470  data-cardSizes="6x3"
471  data-maxResults="6"></div>
472
473<!-- cost -->
474<div class="headerLine">
475  <h2 id="cost">Data Cost</h2>
476</div>
477<p>Data plans in some countries can cost upwards of 10% of monthly income.
478 Conserve data and give control to optimize user experience. Reduce data
479 consumption and give users control over your app’s use of data.</p>
480
481<h3 id="appsize">Reduce app size</h3>
482<h4 id="appsize-graphics">Reduce APK graphical asset size</h4>
483 <ul>
484  <li>Graphical assets are often the largest contributor to the size of the
485   APK. Optimizing these can result in smaller downloads and thus faster
486   installation times for users.</li>
487  <li>For graphical assets like icons, use Scalable Vector Graphics (SVG)
488   format. SVG images are relatively tiny in size and can be rendered at
489   runtime to any resolution. The <a
490   href="{@docRoot}tools/support-library/index.html">Android Support</a>
491   library provides a backward-compatible implementation for vector resources as
492   far back as Android 2.1 (API level 7). Get started with vectors with <a
493   class="external-link"
494   href="https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88">
495   this Medium post</a>. </li>
496  <li>For non-vector images, like photos, use <a
497   href="https://developers.google.com/speed/webp/">WebP</a>. WebP reduces
498   image load times, saves network bandwidth, and is proven to result in
499   smaller file sizes than its PNG and JPG counterparts, with at least the
500   same image quality. Even at lossy settings, WebP can produce a nearly
501   identical image. Android has had lossy WebP support since Android 4.0 (API
502   level 14: Ice Cream Sandwich) and support for lossless / transparent WebP
503   since Android 4.2 (API level 17: Jelly Bean).</li>
504  <li>If you have many large images across multiple densities, consider
505   using <a href="{@docRoot}google/play/publishing/multiple-apks.html">Multiple
506   APK support</a> to split your APK by density. This results in builds
507   targeted for specific densities, meaning users with low-density devices
508   won’t have to incur the penalty of unused high-density assets.</li>
509  <li>For more information about reducing APK size, see
510  <a href="/topic/performance/reduce-apk-size.html">Reduce APK Size</a> and
511  <a href="/studio/build/shrink-code.html">Shrink Your Code and Resources</a>. In addition, you can
512  find a detailed guide on reducing APK size in this <a class="external-link"
513  href="https://medium.com/@wkalicinski/smallerapk-part-4-multi-apk-through-abi-and-density-splits-477083989006">
514   series of Medium posts</a>.</li>
515 </ul>
516<h4 id="appsize-code">Reduce code size</h4>
517 <ul>
518  <li>Be careful about using external libraries because not all libraries are
519   meant to be used in mobile apps. Ensure that the libraries your app is
520   using are optimized for mobile use.</li>
521  <li>Every library in your Android project is adding potentially unused code
522   to your APK. There are also some libraries that aren’t designed with mobile
523   development in mind. These libraries can end up contributing to significant
524   APK bloat.</li>
525  <li>Consider optimizing your compiled code using a tool such as <a
526   href="{@docRoot}tools/help/proguard.html">ProGuard</a>. ProGuard identifies
527   code that isn’t being used and removes it from your APK. Also <a
528   class="external-link"
529   href="http://tools.android.com/tech-docs/new-build-system/resource-shrinking">
530   enable resource shrinking</a> at build time by setting
531   <code>minifyEnabled=true</code>, <code>shrinkResources=true</code> in
532   <code>build.gradle</code>—this automatically removes unused resources from
533   your APK.</li>
534  <li>When using Google Play services, you should <a
535   href="{@docRoot}google/play-services/setup.html#add_google_play_services_to_your_project">
536   selectively include</a> only the necessary APIs into your APK.</li>
537  <li>For more information on reducing code size in your APK, see the Android
538   training on how to <a
539   href="{@docRoot}training/articles/memory.html#DependencyInjection">Avoid
540   dependency injection frameworks</a>.</li>
541 </ul>
542<h4 id="appsize-external">Allow app to be moved to external (SD) storage</h4>
543 <ul>
544  <li>Low-cost devices often come with little on-device storage. Users can
545   extend this with SD cards; however, apps need to explicitly declare that
546   they support being installed to external storage before users can move them.
547  </li>
548  <li>Allow your app to be installed to external storage using the <a
549   href="{@docRoot}guide/topics/manifest/manifest-element.html#install"><code>
550   android:installLocation</code></a> flag in your AndroidManifest. For more
551   information on enabling your app to be moved to external storage, see the
552   Android guide on <a
553   href="{@docRoot}guide/topics/data/install-location.html">App Install
554   Location</a>.</li>
555 </ul>
556
557<h4 id="appsize-postinstall">Reduce post-install app disk usage</h4>
558 <ul>
559  <li>Keeping your app’s disk usage low means that users are less likely to
560   uninstall your app when the device is low on free space. When using caches,
561   it’s important to apply bounds around your caches—this prevents your app’s
562   disk usage from growing indefinitely. Be sure you put your cached data in
563   {@link android.content.Context#getCacheDir()}—the system can delete files
564   placed here as needed, so they won’t show up as storage committed to the
565   app.</li>
566 </ul>
567
568<h3 id="configurablenetwork">Offer configurable network usage</h3>
569<h4 id="configurablenetwork-onboarding">Provide onboarding experiences for
570subjective user choices</h4>
571 <ul>
572  <li>Apps that allow users to reduce data usage are well received, even if
573   they demand heavy data requirements. If your app uses a considerable amount
574   of bandwidth (for example, video streaming apps), you can provide an
575   onboarding experience for users to configure network usage. For example,
576   you could allow the user to force lower-bitrate video streams on cellular
577   networks. </li>
578  <li>Additional settings for users to control data syncing, prefetching, and
579   network usage behavior (for example, prefetch all starred news categories on
580   Wi-Fi only), also help users tailor your app’s behavior to their needs.</li>
581  <li>For more information on managing network usage, see the Android training
582   on <a href="{@docRoot}training/basics/network-ops/managing.html">Managing
583   Network Usage</a>.</li>
584 </ul>
585<h4 id="configurablenetwork-preferences">Provide a network preferences
586screen</h4>
587 <ul>
588  <li>You can navigate to the app’s network settings from outside the app by
589   means of a network preferences screen. You can invoke this screen from
590   either the system settings screen or the system data usage screen.</li>
591  <li>To provide a network preferences screen that users can access from within
592   your app as well as from the system settings, in your app include an
593   activity that supports the
594   {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action.</li>
595  <li>For further information on adding a network preferences screen, see the
596   Android training on <a
597   href="{@docRoot}training/basics/network-ops/managing.html#prefs">
598   Implementing a Preferences Activity</a>.</li>
599 </ul>
600
601
602
603<h3 class="rel-resources clearfloat">Related resources</h3>
604<div class="resource-widget resource-flow-layout col-13"
605  data-query="collection:distribute/essentials/billionsquality/cost"
606  data-sortOrder="-timestamp"
607  data-cardSizes="6x3"
608  data-maxResults="6"></div>
609
610
611<!-- consumption -->
612<div class="headerLine">
613  <h2 id="consumption">Battery Consumption</h2>
614</div>
615<p>Access to reliable power supplies varies, and outages can disrupt planned
616charges. Defend your users' batteries against unnecessary drain by benchmarking
617your battery use,  avoiding wakelocks, scheduling tasks, and monitoring sensor
618requests.</p>
619<h3 id="consumption-reduce">Reduce battery consumption</h3>
620 <ul>
621  <li>Your app should do minimal activity when in the background and when the
622   device is running on battery power.</li>
623   <li>Sensors, like GPS, can also significantly drain your battery. For this
624   reason, we recommend that you use the <a
625   href="https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi">
626   <code>FusedLocationProvider</code></a> API. The
627   <code>FusedLocationProvider</code> API manages the
628   underlying location technology and provides a simple API so that you can
629   specify requirements&mdash;like high accuracy or low power&mdash;at a high
630   level. It also optimizes the device's use of battery power by caching
631   locations and batching requests across apps. For more information about the
632   ideal ways to request location, see the <a
633   href="{@docRoot}training/location/retrieve-current.html">Getting the Last
634   Known Location</a> training guide.
635  </li>
636  <li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wake
637   locks</a> are mechanisms to keep devices on so that they can perform
638   background activities. Avoid using wake locks because they prevent the
639   device from going into low-power states.</li>
640  <li>To reduce the number of device wake-ups, batch network activity. For more
641   information on batching, see the Android training on <a
642   href="{@docRoot}training/efficient-downloads/efficient-network-access.html">
643   Optimizing Downloads for Efficient Network Access</a>.</li>
644  <li><a
645   href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
646   <code>GcmNetworkManager</code></a> schedules tasks and lets Google Play
647   services batch operations across the system. This greatly
648   simplifies the implementation of common patterns, such as waiting for
649   network connectivity, device charging state, retries, and backoff. Use
650   <code>GcmNetworkManager</code> to perform non-essential background activity
651   when the device is charging and is connected to an unmetered network.</li>
652  <li>For more information on how network activity can drain the battery, and
653  how to tackle this issue, see <a
654  href="/topic/performance/power/network/index.html">Reducing Network Battery Drain</a>.
655 </ul>
656<h3 id="consumption-benchmark">Benchmark battery usage</h3>
657 <ul>
658  <li>Benchmarking your app’s usage in a controlled environment helps you
659   understand the battery-heavy tasks in your app. It is a good practice to
660   benchmark your app’s battery usage to gauge efficiency and track changes
661   over time.
662</li>
663  <li><a
664   href="{@docRoot}tools/performance/batterystats-battery-historian/index.html">
665   Batterystats</a> collects battery data about your apps, and <a
666   href="{@docRoot}tools/performance/batterystats-battery-historian/index.html">
667   Battery Historian</a> converts that data into an HTML visualization. For
668   more information on reducing battery usage, see the Android training on <a
669   href="{@docRoot}training/monitoring-device-state/index.html">Optimizing
670   Battery Life</a>.</li>
671 </ul>
672
673<h3 class="rel-resources clearfloat">Related resources</h3>
674<div class="resource-widget resource-flow-layout col-13"
675  data-query="collection:distribute/essentials/billionsquality/consumption"
676  data-sortOrder="-timestamp"
677  data-cardSizes="6x3"
678  data-maxResults="6"></div>
679
680<!-- content -->
681<div class="headerLine">
682  <h2 id="contentsection">Content</h2>
683</div>
684<p>Make sure that your app works well on a variety of screens: offering good,
685 crisp graphics and appropriate layouts on low resolution and physically small
686 screens. Ensure that your app is designed to be easily localized by
687 accommodating the variations between languages: allow for spacing, density,
688 order, emphasis, and wording variations. Also make sure that date, time, and
689 the like are internationalized and displayed according to the phone’s
690 settings.</p>
691
692<h3 id="content-responsive">Fast and responsive UI</h3>
693<h4 id="content-feedback">Touch feedback on all touchable items</h4>
694 <ul>
695  <li>Touch feedback adds a tactile feeling to the user interface. You should
696   ensure your app provides touch feedback on all touchable elements to reduce
697   the perceived app latency as much as possible.
698</li>
699  <li><a
700   href="https://www.google.com/design/spec/animation/responsive-interaction.html">
701   Responsive interaction</a> encourages deeper exploration of an app by
702   creating timely, logical, and delightful screen reactions to user input.
703   Responsive interaction elevates an app from an information-delivery service
704   to an experience that communicates using multiple visual and tactile
705   responses.</li>
706  <li>For more information, see the Android training on <a
707   href="{@docRoot}training/material/animations.html#Touch">Customizing Touch
708   Feedback</a>.</li>
709 </ul>
710<h4 id="content-interactive">UI should always be interactive</h4>
711 <ul>
712  <li>Apps that are unresponsive when performing background activity feel slow
713   and reduce user satisfaction. Ensure your app always has a responsive UI
714   regardless of any background activity. Achieve this by performing network
715   operations or any heavy-duty operations in a background thread—keep the UI
716   thread as idle as you can.</li>
717  <li>Material Design apps use minimal visual changes when your app is loading
718   content by representing each operation with a single activity indicator.
719   Avoid blocking dialogs with <a
720   href="https://www.google.com/design/spec/components/progress-activity.html">
721   loading indicators</a>.</li>
722  <li><a
723   href="http://www.google.com/design/spec/patterns/empty-states.html">Empty
724   states</a> occur when the regular content of a view can’t be shown. It might
725   be a list that has no items or a search that returns no results. Avoid
726   completely empty states. The most basic empty state displays a
727   non-interactive image and a text tagline. Where you don’t have an image, or
728   the image is still loading, you should always show either a static
729   placeholder, or create a dynamic placeholder by using the <a
730   href="{@docRoot}tools/support-library/features.html#v7-palette">Palette
731   library</a> to generate placeholder colors that match the target image.</li>
732  <li>For more information, see the Android training on <a
733   href="{@docRoot}training/articles/perf-anr.html">Keeping Your App
734   Responsive</a>.</li>
735 </ul>
736<h4 id="content-60fps">Target 60 frames per second on low-cost devices</h4>
737 <ul>
738  <li>Ensure that your app always runs fast and smoothly, even on low-cost
739   devices.</li>
740  <li>Overdraw can significantly slow down your app—it occurs when the pixels
741   are being drawn more than once per pass. An example of this is when you have
742   an image with a button placed on top of it. While some overdraw is
743   unavoidable, it should be minimized to ensure a smooth frame rate. Perform
744   <a href="{@docRoot}tools/performance/debug-gpu-overdraw/index.html">Debug
745   GPU overdraw</a> on your app to ensure it is minimized.</li>
746  <li>Android devices refresh the screen at 60 frames per second (fps), meaning
747   your app has to update the screen within roughly 16 milliseconds. <a
748   href="{@docRoot}tools/performance/profile-gpu-rendering/index.html">Profile
749   your app</a> using on-device tools to see if and when your app is not
750   meeting this 16-ms average.</li>
751  <li>Reduce or remove animations on low-cost devices to lessen the burden on
752   the device’s CPU and GPU.  For more information, see the Android training on
753   <a href="{@docRoot}training/improving-layouts/index.html">Improving Layout
754   Performance</a>. </li>
755  <li>An efficient view hierarchy can speed up your app without increasing the
756      app's memory footprint. For more information, see
757  <a href="/topic/performance/optimizing-view-hierarchies.html">Performance
758  and View Hierarchies.</a>
759 </ul>
760<h4 id="content-firstload">If anticipated start speed is low, use launch screen on first load</h4>
761 <ul>
762  <li>The launch screen is a user’s first experience of your application.
763   Launching your app while displaying a blank canvas increases its perceived
764   loading time, so consider using a placeholder UI or a branded launch screen
765   to reduce the perceived loading time.</li>
766  <li>A<a href="https://www.google.com/design/spec/patterns/launch-screens.html#launch-screens-types-of-launch-screens">
767   placeholder UI</a> is the most seamless launch transition, appropriate for
768   both app launches and in-app activity transitions.</li>
769  <li><a
770   href="https://www.google.com/design/spec/patterns/launch-screens.html#launch-screens-placeholder-ui">
771   Branded launch screens</a> provide momentary brand exposure, freeing the UI
772   to focus on content.</li>
773  <li>For more information on implementing splash screens, see the <a
774   href="https://www.google.com/design/spec/patterns/launch-screens.html">
775   Launch screens</a> section of the Material Design spec.</li>
776  <li>The best way to deal with slow start speeds is not to have them. <a
777  href="/topic/performance/launch-time.html">Launch-Time Performance</a> provides
778  information that may help you speed up your app's launch time.</li>
779 </ul>
780<h3 id="ui">UI best practices</h3>
781 <ul>
782  <li><a
783   href="https://www.google.com/design/spec/material-design/introduction.html">
784   Material Design</a> is a visual language that synthesizes the classic
785   principles of good design with the innovation and possibility of technology
786   and science. Material Design aims to develop a single underlying system that
787   allows for a unified experience across platforms and device sizes. Consider
788   using key Material Design components so that users intuitively know how to
789   use your app.</li>
790  <li>Ready-to-use Material Design components are available via the <a
791   href="{@docRoot}tools/support-library/features.html#design">Design Support
792   library</a>. These components are supported in Android 2.1 (API level 7) and
793   above.</li>
794 </ul>
795<h3 id="localization">Localization</h3>
796 <ul>
797  <li>Your users could be from any part of the world and their first language
798   may not be yours. If you don’t present your app in a language that your
799   users can read, it is a missed opportunity. You should therefore
800   localize your app for key regional languages.</li>
801  <li>To learn more, visit the Android training on <a
802 href="{@docRoot}training/basics/supporting-devices/languages.html">
803 Supporting Different Languages</a>.</li>
804  <li>Starting from Android 7.0 (API level 24), the Android framework
805  makes available a subset of the <a class="external-link"
806  href="http://userguide.icu-project.org/">ICU4J APIs</a>, which can
807  help you localize your app into multiple languages. For more
808  information, see <a href="/guide/topics/resources/icu4j-framework.html">
809  ICU4J Android Framework APIs.</a>
810 </ul>
811
812<h3 class="rel-resources clearfloat">Related resources</h3>
813<div class="resource-widget resource-flow-layout col-13"
814  data-query="collection:distribute/essentials/billionsquality/content"
815  data-sortOrder="-timestamp"
816  data-cardSizes="6x3"
817  data-maxResults="6"></div>
818