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—on behalf of the user—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—like high accuracy or low power—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