diff options
| -rw-r--r-- | docs/html/distribute/essentials/_book.yaml | 3 | ||||
| -rw-r--r-- | docs/html/distribute/essentials/essentials_toc.cs | 6 | ||||
| -rw-r--r-- | docs/html/distribute/essentials/quality/billions.jd | 778 | ||||
| -rw-r--r-- | docs/html/distribute/images/billions-guidelines.png | bin | 0 -> 951 bytes | |||
| -rw-r--r-- | docs/html/jd_extras_en.js | 66 |
5 files changed, 853 insertions, 0 deletions
diff --git a/docs/html/distribute/essentials/_book.yaml b/docs/html/distribute/essentials/_book.yaml index 6a2c8f52ebf2..222cb361277a 100644 --- a/docs/html/distribute/essentials/_book.yaml +++ b/docs/html/distribute/essentials/_book.yaml @@ -20,6 +20,9 @@ toc: - title: Auto App Quality path: /distribute/essentials/quality/auto.html +- title: Building for Billions + path: /distribute/essentials/quality/billions.html + - title: Launch Checklist path: /distribute/tools/launch-checklist.html path_attributes: diff --git a/docs/html/distribute/essentials/essentials_toc.cs b/docs/html/distribute/essentials/essentials_toc.cs index a78252db7843..374f3385124e 100644 --- a/docs/html/distribute/essentials/essentials_toc.cs +++ b/docs/html/distribute/essentials/essentials_toc.cs @@ -29,6 +29,12 @@ </a> </div> </li> + <li class="nav-section"> + <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/billions.html"> + <span class="en">Building for Billions</span> + </a> + </div> + </li> <li class="nav-section"> <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/tools/launch-checklist.html" zh-cn-lang="发布检查清单"> diff --git a/docs/html/distribute/essentials/quality/billions.jd b/docs/html/distribute/essentials/quality/billions.jd new file mode 100644 index 000000000000..58f15a39c630 --- /dev/null +++ b/docs/html/distribute/essentials/quality/billions.jd @@ -0,0 +1,778 @@ +page.title=Building for Billions +page.metaDescription=Best practices on how to optimize Android apps for low- and no-bandwidth and low-cost devices. +page.image=/distribute/images/billions-guidelines.png + +@jd:body + +<!-- table of contents --> +<div id="qv-wrapper"><div id="qv"> +<h2><a href="#connectivity">Connectivity</a></h2> + <ol> + <li><a href="#images">Optimize images</a></li> + <li><a href="#network">Optimize networking</a></li> + <li><a href="#transfer">Fine-tune data transfer</a></li> + </ol> +<h2><a href="#capability">Device Capability</a></h2> + <ol> + <li><a href="#screens">Support varying screen sizes</a></li> + <li><a href="#compatibility">Backward compatibility</a></li> + <li><a href="#memory">Efficient memory usage</a></li> + </ol> + +<h2><a href="#cost">Data Cost</a></h2> + <ol> + <li><a href="#appsize">Reduce app size</a></li> + <li><a href="#configurablenetwork">Offer configurable network usage</a></li> + </ol> + +<h2><a href="#consumption">Battery Consumption</a></h2> + <ol> + <li><a href="#consumption-reduce">Reduce battery consumption</a></li> + <li><a href="#consumption-benchmark">Benchmark battery usage</a></li> + </ol> + +<h2><a href="#contentsection">Content</a></h2> + <ol> + <li><a href="#content-responsive">Fast and responsive UI</a></li> + <li><a href="#ui">UI Best practices</a></li> + <li><a href="#localization">Localization</a></li> + </ol> +</div> +</div> + +<!-- intro --> +<p>Internet use—and smartphone penetration—is growing fastest in markets with + low, intermittent, or expensive connectivity. Successful apps in these + markets need to perform across a variety of speeds and devices, as well as + conserve and share information about battery and data consumption.</p> + +<p>To help you address these important considerations, we’ve compiled the + following checklist. These do not follow a particular order, and as + always it's a good idea to research particularities of any market or country + you're targeting. +</p> + +<!-- connectivity --> +<div class="headerLine"> + <h2 id="connectivity">Connectivity</h2> +</div> + +<p>Over half of the users in the world still experience your app over 2G + connections. To improve their experience, optimize for no- and low-connection + speeds. For offline and slow connections: store data, queue requests, and handle + images for optimal performance. +</p> + +<h3 id="images">Optimize images</h3> +<h4 id="images-format">Serve WebP images</h4> + <ul> + <li>Serve <a + href="https://developers.google.com/speed/webp/">WebP</a> files over the + network. WebP reduces image load times, saves network bandwidth, and often + results in smaller file sizes than its PNG and JPG counterparts, with at + least the same image quality. Even at lossy settings, WebP can produce a + nearly identical image. Android has had lossy <a + href="{@docRoot}guide/appendix/media-formats.html">WebP support</a> since + Android 4.0 (API level 14: Ice Cream Sandwich) and support for lossless / + transparent WebP since Android 4.2 (API level 17: Jelly Bean).</li> + </ul> +<h4 id="images-sizing">Dynamic image sizing</h4> + <ul> + <li>Have your apps request images at the targeted rendering size, and have + your server provide those images to fit; the target rendering size will + vary based on device specifications. Doing this minimizes the network + overhead and reduces the amount of memory needed to hold each image, + resulting in improved performance and user satisfaction.</li> + <li>Your user experience degrades when users are waiting for images to + download. Using appropriate image sizes helps to address these issues. + Consider making image size requests based on network type or network + quality; this size could be smaller than the target rendering size.</li> + <li>Dynamic placeholders like <a + href="{@docRoot}reference/android/support/v7/graphics/Palette.html"> + pre-computed palette values</a> or low-resolution thumbnails can improve + the user experience while the image is being fetched.</li> + </ul> +<h4 id="images-libraries">Use image loading libraries</h4> + <ul> + <li>Your app should not have to fetch any image more than once. Image + loading libraries such as <a class="external-link" + href="https://github.com/bumptech/glide">Glide</a> and <a + class="external-link" href="http://square.github.io/picasso/">Picasso</a> + fetch the image, cache it, and provide hooks into your Views to show + placeholder images until the actual images are ready. Because images are + cached, these libraries return the local copy the next time they are + requested.</li> + <li>Image-loading libraries manage their cache, holding onto the most recent + images so that your app storage doesn’t grow indefinitely.</li> + </ul> + +<h3 id="network">Optimize networking</h3> +<h4 id="network-offline">Make your app usable offline</h4> + <ul> + <li>In places like subways, planes, elevators, and parking garages, it is + common for devices to lose network connectivity. Creating a useful offline + state results in users being able to interact with the app at all times, by + presenting cached information. Ensure that your app is usable offline or + when network connectivity is poor by storing data locally, caching data, + and queuing outbound requests for when connectivity is restored.</li> + <li>Where possible, apps should not notify users that connectivity has + been lost. It is only when the user performs an operation where connectivity + is essential that the user needs to be notified.</li> + <li>When a device lacks connectivity, your app should batch up network + requests—on behalf of the user—that can be executed when + connectivity is restored. An example of this is an email client that allows + users to compose, send, read, move, and delete existing mails even when the + device is offline. These operations can be cached and executed when + connectivity is restored. In doing so, the app is able to provide a similar + user experience whether the device is online or offline.</li> + </ul> +<h4 id="network-arch">Use GcmNetworkManager and/or Content Providers</h4> + <ul> + <li>Ensure that your app stores all data on disk via a database or similar + structure so that it performs optimally regardless of network conditions + (for example, via SQLite + ContentProvider). The <a + href="https://developers.google.com/cloud-messaging/network-manager"> + GCM Network Manager</a> + (<a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager"> + <code>GcmNetworkManager</code></a>) can result in a robust mechanism to + sync data with servers while <a + href="{@docRoot}guide/topics/providers/content-providers.html">content + providers</a> ({@link android.content.ContentProvider}) cache that data, + combining to provide an architecture that enables a useful offline state.</li> + <li>Apps should cache content that is fetched from the network. Before making + subsequent requests, apps should display locally cached data. This ensures + that the app is functional regardless of whether the device is offline or + on a slow/unreliable network.</li> + </ul> +<h4 id="network-duplicate">Deduplicate network requests</h4> + <ul> + <li>An offline-first architecture initially tries to fetch data from local + storage and, failing that, requests the data from the network. After being + retrieved from the network, the data is cached locally for future + retrieval. This helps to ensure that network requests for the same piece of + data only occur once—the rest of the requests are satisfied locally. To + achieve this, use a local database for long-lived data (usually + {@link android.database.sqlite} or + {@link android.content.SharedPreferences}).</li> + <li>An offline-first architecture always looks for data locally first, then + makes the request over the network. The response is cached and then returned + locally. Such an architecture simplifies an app’s flow between offline and + online states as one side fetches from the network to the cache, while the + other retrieves data from the cache to present to the user.</li> + <li>For transitory data, use a bounded disk cache such as a <a class="external-link" + href="https://github.com/JakeWharton/DiskLruCache"><code>DiskLruCache</code> + </a>. Data that doesn’t typically change should only be requested once over + the network and cached for future use. Examples of such data are images and + non-temporal documents like news articles or social posts.</li> + </ul> + +<h3 id="transfer">Fine-tune data transfer</h3> +<h4 id="transfer-prioritize">Prioritize bandwidth</h4> + <ul> + <li>Writers of apps should not assume that any network that the device is + connected to is long-lasting or reliable. For this reason, apps should + prioritize network requests to display the most useful information to the + user as soon as possible.</li> + <li>Presenting users with visible and relevant information immediately is a + better user experience than making them wait for information that might not + be necessary. This reduces the time that the user has to wait and + increases the usefulness of the app on slow networks.</li> + <li>To achieve this, sequence your network requests such that text is + fetched before rich media. Text requests tend to be smaller, compress + better, and hence transfer faster, meaning that your app can display useful + content quickly. For more information on managing network requests, visit + the Android training on <a + href="{@docRoot}training/basics/network-ops/managing.html">Managing Network + Usage</a>.</li> + </ul> +<h4 id="network-bandwidth">Use less bandwidth on slower connections</h4> + <ul> + <li>The ability for your app to transfer data in a timely fashion is + dependent on the network connection. Detecting the quality of the network + and adjusting the way your app uses it can help provide an excellent user + experience.</li> + <li>You can use the following methods to detect the underlying network + quality. Using the data from these methods, your app should tailor its use + of the network to continue to provide a timely response to user actions: + <ul> + <li>{@link android.net.ConnectivityManager}> + {@link android.net.ConnectivityManager#isActiveNetworkMetered}</li> + <li>{@link android.net.ConnectivityManager}> + {@link android.net.ConnectivityManager#getActiveNetworkInfo}</li> + <li>{@link android.net.ConnectivityManager}> + {@link android.net.ConnectivityManager#getNetworkCapabilities}</li> + <li>{@link android.telephony.TelephonyManager}> + {@link android.telephony.TelephonyManager#getNetworkType}</li> + </ul> + </li> + <li>On slower connections, consider downloading only lower-resolution media + or perhaps none at all. This ensures that your users are still able to use + the app on slow connections. Where you don’t have an image or the image is + still loading, you should always show a placeholder. You can create a + dynamic placeholder by using the <a + href="{@docRoot}tools/support-library/features.html#v7-palette"> + Palette library</a> to generate placeholder colors that match the target + image.</li> + <li>Prioritize network requests such that text is fetched before rich media. + Text requests tend to be smaller, compress better, and hence transfer + faster, meaning that your app can display useful content quickly. For more + information on adjusting bandwidth based on network connection, see the + Android training on <a + href="{@docRoot}training/basics/network-ops/managing.html">Managing Network + Usage</a>.</li> + </ul> +<h4 id="network-behavior">Detect network changes, then change app behavior</h4> + <ul> + <li>Network quality is not static; it changes based on location, network + traffic, and local population density. Apps should detect changes in + network and adjust bandwidth accordingly. By doing so, your app can tailor + the user experience to the network quality. Detect network state using + these methods: + <ul> + <li>{@link android.net.ConnectivityManager}> + {@link android.net.ConnectivityManager#getActiveNetworkInfo}</li> + <li>{@link android.net.ConnectivityManager}> + {@link android.net.ConnectivityManager#getNetworkCapabilities}</li> + <li>{@link android.telephony.TelephonyManager}> + {@link android.telephony.TelephonyManager#getDataState}</li> + </ul> + </li> + <li>As the network quality degrades, scale down the number and size of + requests. As the connection quality improves, you can scale up your + requests to optimal levels.</li> + <li>On higher quality, unmetered networks, consider <a + href="{@docRoot}training/efficient-downloads/efficient-network-access.html#PrefetchData"> + prefetching data</a> to make it available ahead of time. From a user + experience standpoint, this might mean that news reader apps only fetch + three articles at a time on 2G but fetch twenty articles at a time on + Wi-Fi. For more information on adjusting app behavior based on network changes, + visit the Android training on <a + href="{@docRoot}training/monitoring-device-state/connectivity-monitoring.html"> + Monitoring the Connectivity Status</a>.</li> + <li>The broadcast <a + href="{@docRoot}reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION"> + <code>CONNECTIVITY_CHANGE</code></a> is sent when a change in network + connectivity occurs. When your app is in the foreground, you can call <a + href="{@docRoot}reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter)"> + <code>registerReceiver</code></a> to receive this broadcast. After receiving + the broadcast, you should reevaluate the current network state and adjust + your UI and network usage appropriately. You should not declare this receiver + in your manifest, as it will no longer function beginning with Android N. + For more details see <a href="{@docRoot}preview/behavior-changes.html"> + Android N behavior changes</a>.</li> + </ul> + +<h3 class="rel-resources clearfloat">Related resources</h3> +<div class="resource-widget resource-flow-layout col-13" + data-query="collection:distribute/essentials/billionsquality/connectivity" + data-sortOrder="-timestamp" + data-cardSizes="6x3" + data-maxResults="6"></div> + +<!-- capability --> +<div class="headerLine"> + <h2 id="capability">Device Capability</h2> +</div> +<p>Reaching new users means supporting an increasing variety of Android + platform versions and device specifications. Optimize for common RAM and + screen sizes and resolutions to improve the user experience. </p> + +<h3 id="screens">Support varying screen sizes</h3> +<h4 id="screens-dp">Use density-independent pixels (dp)</h4> + <ul> + <li>Defining layout dimensions with pixels is a problem because different + screens have different pixel densities, so the same number of pixels may + correspond to different physical sizes on different devices. The + density-independent pixel (dp) corresponds to the physical size of a pixel + at 160 dots per inch (mdpi density).</li> + <li>Defining layouts with dp ensures that the physical size of your user + interface is consistent regardless of device. Visit the Android + guide on <a + href="https://developer.android.com/guide/practices/screens_support.html"> + Supporting Multiple Screens</a> for best practices using + density-independent pixels.</li> + </ul> +<h4 id="screens-density">Test graphics on ldpi/mdpi screen densities</h4> + <ul> + <li>Ensure that your app layouts work well on low- and medium-density + (ldpi/mdpi) screens because these are <a + href="https://developer.android.com/about/dashboards/index.html#Screens"> + common densities</a>, especially in lower-cost devices. Testing on + lower-density screens helps to validate that your layouts are legible on + lower-density screens.</li> + <li>Lower-density screens can result in unclear text where the finer details + aren't visible. The Material Design guidelines describe <a + class="external-link" href="https://www.google.com/design/spec/layout/metrics-keylines.html"> + metrics and keylines</a> to ensure that your layouts can scale across + screen densities.</li> + <li>Devices with lower-density screens tend to have lower hardware + specifications. To ensure that your app performs well on these devices, + consider reducing or eliminating heavy loads, such as animations and + transitions. For more information on supporting different densities, see + the Android training on <a + href="https://developer.android.com/training/multiscreen/screendensities.html"> + Supporting Different Densities</a>.</li> + </ul> +<h4 id="screens-sizes">Test layouts on small/medium screen sizes</h4> + <ul> + <li>Validate that your layouts scale down by testing on smaller screens. As + screen sizes shrink, be very selective about visible UI elements, because + there is limited space for them.</li> + <li>Devices with smaller screens tend to have lower hardware specifications. + To ensure that your app performs well on these devices, try reducing or + eliminating heavy loads, such as animations or transitions. For more + information on supporting different screen sizes, see the Android + training on <a + href="https://developer.android.com/training/multiscreen/screendensities.html"> + Supporting Different Screen Sizes</a>.</li> + </ul> + +<h3 id="compatibility">Backward compatibility</h3> +<h4 id="compatibility-sdkversion">Set your targetSdkVersion and minSdkVersion + appropriately</h4> + <ul> + <li>Apps should build and target a recent version of Android to ensure most + current behavior across a broad range of devices; this still provides + backward compatibility to older versions. Here are the best practices for + targeting API levels appropriately: + <ul> + <li><a + href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target"> + {@code targetSdkVersion}</a> should be the latest version of Android. + Targeting the most recent version ensures that your app inherits newer + runtime behaviors when running newer versions of Android. Be sure to + test your app on newer Android versions when updating the + targetSdkVersion as it can affect app behavior.</li> + <li><a + href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min"> + {@code minSdkVersion}</a> sets the minimum supported Android version. + Use Android 4.0 (API level 14: Ice Cream Sandwich) or Android 4.1 (API + level 16: Jelly Bean)—these versions give maximum coverage for modern + devices. Setting {@code minSdkVersion} also results in the Android build + tools reporting incorrect use of new APIs that might not be available in + older versions of the platform. By doing so, developers are protected + from inadvertently breaking backward compatibility.</li> + </ul> + </li> + <li>Consult the <a + href="https://developer.android.com/about/dashboards/index.html#Platform"> + Android dashboards</a>, the <a class="external-link" + href="https://play.google.com/apps/publish/">Google Play Developer + Console</a> for your app, and industry research in your target markets to + gauge which versions of Android to target, based on your target users.</li> + </ul> +<h4 id="compatibility-libraries">Use the Android Support libraries</h4> + <ul> + <li>Ensure your app provides a consistent experience across OS versions by + using the Google-provided support libraries such as AppCompat and the Design + Support Library. The Android Support Library package is a set of code + libraries that provides backward-compatible versions of Android framework + APIs as well as features that are only available through the library APIs. + </li> + <li>Some of the the highlights include: + <ul> + <li>v4 & v7 support library: Many framework APIs for older versions of + Android such as {@link android.support.v4.view.ViewPager}, + {@link android.app.ActionBar}, + {@link android.support.v7.widget.RecyclerView}, and + {@link android.support.v7.graphics.Palette}.</li> + <li><a href="{@docRoot}tools/support-library/features.html#design">Design + Support</a> library: APIs to support adding Material Design components + and patterns to your apps.</li> + <li><a href="{@docRoot}tools/support-library/features.html#multidex"> + Multidex Support</a> library: provides support for large apps that have + more than 65K methods. This can happen if your app is using many + libraries.</li> + </ul> + </li> + <li>For more information on the available support libraries, see the <a + href="https://developer.android.com/tools/support-library/features.html"> + Support Libraries Features</a> section of the Android Developer site.</li> + </ul> +<h4 id="compatibility-playservices">Use Google Play services</h4> + <ul> + <li>Google Play services brings the best of Google APIs independent of + Android platform version. Consider using features from Google Play services + to offer the most streamlined Google experience on Android devices.</li> + <li>Google Play services also include useful APIs such as <a + href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager"> + <code>GcmNetworkManager</code></a>, which provides much of Android 5.0’s + {@link android.app.job.JobScheduler} API for older versions of Android. </li> + <li>Updates to Google Play services are distributed automatically by the + Google Play Store, and new versions of the client library are delivered + through the Android SDK Manager. </li> + </ul> +<h3 id="memory">Efficient memory usage</h3> +<h4 id="memory-footprint">Reduce memory footprint on low-cost devices</h4> + <ul> + <li>Adjusting your memory footprint dynamically helps to ensure compatibility + across devices with different RAM configurations.</li> + <li>Methods such as {@link android.app.ActivityManager#isLowRamDevice} and + {@link android.app.ActivityManager#getMemoryClass()} help determine memory + constraints at runtime. Based on this information, you can scale down your + memory usage. As an example, you can use lower resolution images on low memory + devices.</li> + <li>For more information on managing your app’s memory, see the Android + training on <a href="{@docRoot}training/articles/memory.html">Managing + Your App's Memory</a>.</li> + </ul> +<h4 id="memory-longprocesses">Avoid long-running processes</h4> + <ul> + <li>Long-running processes stay resident in memory and can result in slowing + down the device. In most situations, your app should wake up for a given + event, process data, and shut down. You should use <a + href="https://developers.google.com/cloud-messaging">Google Cloud Messaging + (GCM)</a> and/or <a + href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager"> + <code>GcmNetworkManager</code></a> to avoid long running background + services and reduce memory pressure on the user’s device.</li> + </ul> +<h4 id="memory-benchmark">Benchmark memory usage</h4> + <ul> + <li>Android Studio provides memory benchmarking and profiling tools, enabling + you to measure memory usage at run time. Benchmarking your app’s memory + footprint enables you to monitor memory usage over multiple versions of + the app. This can help catch unintentional memory footprint growth. These + tools can be used in the following ways: + <ul> + <li>Use the <a + href="{@docRoot}tools/performance/memory-monitor/index.html">Memory + Monitor</a> tool to find out whether undesirable garbage collection (GC) + event patterns might be causing performance problems.</li> + <li>Run <a + href="{@docRoot}tools/performance/heap-viewer/index.html">Heap Viewer</a> + to identify object types that get or stay allocated unexpectedly or + unnecessarily.</li> + <li>Use <a + href="{@docRoot}tools/performance/allocation-tracker/index.html"> + Allocation Tracker</a> to identify where in your code the problem might + be.</li> + </ul> + </li> + <li>For more information on benchmarking memory usage, see the <a + href="{@docRoot}tools/performance/comparison.html"> + Memory Profilers</a> tools on the Android Developers site.</li> + </ul> + +<h3 class="rel-resources clearfloat">Related resources</h3> +<div class="resource-widget resource-flow-layout col-13" + data-query="collection:distribute/essentials/billionsquality/capability" + data-sortOrder="-timestamp" + data-cardSizes="6x3" + data-maxResults="6"></div> + +<!-- cost --> +<div class="headerLine"> + <h2 id="cost">Data Cost</h2> +</div> +<p>Data plans in some countries can cost upwards of 10% of monthly income. + Conserve data and give control to optimize user experience. Reduce data + consumption and give users control over your app’s use of data.</p> + +<h3 id="appsize">Reduce app size</h3> +<h4 id="appsize-graphics">Reduce APK graphical asset size</h4> + <ul> + <li>Graphical assets are often the largest contributor to the size of the + APK. Optimizing these can result in smaller downloads and thus faster + installation times for users.</li> + <li>For graphical assets like icons, use Scalable Vector Graphics (SVG) + format. SVG images are relatively tiny in size and can be rendered at + runtime to any resolution. The <a + href="{@docRoot}tools/support-library/index.html">Android Support</a> + library provides a backward-compatible implementation for vector resources as + far back as Android 2.1 (API level 7). Get started with vectors with <a + class="external-link" + href="https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88"> + this Medium post</a>. </li> + <li>For non-vector images, like photos, use <a + href="https://developers.google.com/speed/webp/">WebP</a>. WebP reduces + image load times, saves network bandwidth, and is proven to result in + smaller file sizes than its PNG and JPG counterparts, with at least the + same image quality. Even at lossy settings, WebP can produce a nearly + identical image. Android has had lossy WebP support since Android 4.0 (API + level 14: Ice Cream Sandwich) and support for lossless / transparent WebP since Android 4.2 (API level 17: Jelly Bean).</li> + <li>If you have many large images across multiple densities, consider + using <a href="{@docRoot}google/play/publishing/multiple-apks.html">Multiple + APK support</a> to split your APK by density. This results in builds + targeted for specific densities, meaning users with low-density devices + won’t have to incur the penalty of unused high-density assets.</li> + <li>A detailed guide on reducing your APK size can be found in <a + class="external-link" href="https://medium.com/@wkalicinski/smallerapk-part-4-multi-apk-through-abi-and-density-splits-477083989006"> + series of Medium posts</a>.</li> + </ul> +<h4 id="appsize-code">Reduce code size</h4> + <ul> + <li>Be careful about using external libraries because not all libraries are + meant to be used in mobile apps. Ensure that the libraries your app is + using are optimized for mobile use.</li> + <li>Every library in your Android project is adding potentially unused code + to your APK. There are also some libraries that aren’t designed with mobile + development in mind. These libraries can end up contributing to significant + APK bloat.</li> + <li>Consider optimizing your compiled code using a tool such as <a + href="{@docRoot}tools/help/proguard.html">ProGuard</a>. ProGuard identifies + code that isn’t being used and removes it from your APK. Also <a + class="external-link" + href="http://tools.android.com/tech-docs/new-build-system/resource-shrinking"> + enable resource shrinking</a> at build time by setting + <code>minifyEnabled=true</code>, <code>shrinkResources=true</code> in + <code>build.gradle</code>—this automatically removes unused resources from + your APK.</li> + <li>When using Google Play services, you should <a + href="{@docRoot}google/play-services/setup.html#add_google_play_services_to_your_project"> + selectively include</a> only the necessary APIs into your APK.</li> + <li>For more information on reducing code size in your APK, see the Android + training on how to <a + href="{@docRoot}training/articles/memory.html#DependencyInjection">Avoid + dependency injection frameworks</a>.</li> + </ul> +<h4 id="appsize-external">Allow app to be moved to external (SD) storage</h4> + <ul> + <li>Low-cost devices often come with little on-device storage. Users can + extend this with SD cards; however, apps need to explicitly declare that + they support being installed to external storage before users can move them. + </li> + <li>Allow your app to be installed to external storage using the <a + href="{@docRoot}guide/topics/manifest/manifest-element.html#install"><code> + android:installLocation</code></a> flag in your AndroidManifest. For more + information on enabling your app to be moved to external storage, see the + Android guide on <a + href="{@docRoot}guide/topics/data/install-location.html">App Install + Location</a>.</li> + </ul> + +<h4 id="appsize-postinstall">Reduce post-install app disk usage</h4> + <ul> + <li>Keeping your app’s disk usage low means that users are less likely to + uninstall your app when the device is low on free space. When using caches, + it’s important to apply bounds around your caches—this prevents your app’s + disk usage from growing indefinitely. Be sure you put your cached data in + {@link android.content.Context#getCacheDir()}—the system can delete files + placed here as needed, so they won’t show up as storage committed to the + app.</li> + </ul> + +<h3 id="configurablenetwork">Offer configurable network usage</h3> +<h4 id="configurablenetwork-onboarding">Provide onboarding experiences for +subjective user choices</h4> + <ul> + <li>Apps that allow users to reduce data usage are well received, even if + they demand heavy data requirements. If your app uses a considerable amount + of bandwidth (for example, video streaming apps), you can provide an + onboarding experience for users to configure network usage. For example, + you could allow the user to force lower-bitrate video streams on cellular + networks. </li> + <li>Additional settings for users to control data syncing, prefetching, and + network usage behavior (for example, prefetch all starred news categories on + Wi-Fi only), also help users tailor your app’s behavior to their needs.</li> + <li>For more information on managing network usage, see the Android training + on <a href="{@docRoot}training/basics/network-ops/managing.html">Managing + Network Usage</a>.</li> + </ul> +<h4 id="configurablenetwork-preferences">Provide a network preferences +screen</h4> + <ul> + <li>You can navigate to the app’s network settings from outside the app by + means of a network preferences screen. You can invoke this screen from + either the system settings screen or the system data usage screen.</li> + <li>To provide a network preferences screen that users can access from within + your app as well as from the system settings, in your app include an + activity that supports the + {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action.</li> + <li>For further information on adding a network preferences screen, see the + Android training on <a + href="{@docRoot}training/basics/network-ops/managing.html#prefs"> + Implementing a Preferences Activity</a>.</li> + </ul> + +<!-- consumption --> +<div class="headerLine"> + <h2 id="consumption">Battery Consumption</h2> +</div> +<p>Access to reliable power supplies varies, and outages can disrupt planned +charges. Defend your users' batteries against unnecessary drain by benchmarking +your battery use, avoiding wakelocks, scheduling tasks, and monitoring sensor +requests.</p> +<h3 id="consumption-reduce">Reduce battery consumption</h3> + <ul> + <li>Your app should do minimal activity when in the background and when the + device is running on battery power.</li> + <li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wake + locks</a> are mechanisms to keep devices on so that they can perform + background activities. Avoid using wake locks because they prevent the + device from going into low-power states.</li> + <li>To reduce the number of device wake-ups, batch network activity. For more + information on batching, see the Android training on <a + href="{@docRoot}training/efficient-downloads/efficient-network-access.html"> + Optimizing Downloads for Efficient Network Access</a>.</li> + <li><a + href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager"> + <code>GcmNetworkManager</code></a> schedules tasks and lets Google Play + services batch operations across the system. This greatly + simplifies the implementation of common patterns, such as waiting for + network connectivity, device charging state, retries, and backoff. Use + <code>GcmNetworkManager</code> to perform non-essential background activity + when the device is charging and is connected to an unmetered network.</li> + <li>Sensors, like GPS, can also have a significant drain on the battery. The + recommended way to request location is to use the FusedLocationProvider API. + The <a + href="https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi">FusedLocationProvider</a> API manages the + underlying location technology and provides a simple API so that you can + specify requirements—like high accuracy or low power—at a high + level. It also optimizes the device's use of battery power by caching + locations and batching requests across apps. For more information on the + ideal ways to request location, see the <a + href="{@docRoot}training/location/retrieve-current.html">Getting the Last + Known Location</a> training guide. + </li> + </ul> +<h3 id="consumption-benchmark">Benchmark battery usage</h3> + <ul> + <li>Benchmarking your app’s usage in a controlled environment helps you + understand the battery-heavy tasks in your app. It is a good practice to + benchmark your app’s battery usage to gauge efficiency and track changes + over time. +</li> + <li><a + href="{@docRoot}tools/performance/batterystats-battery-historian/index.html"> + Batterystats</a> collects battery data about your apps, and <a + href="{@docRoot}tools/performance/batterystats-battery-historian/index.html"> + Battery Historian</a> converts that data into an HTML visualization. For + more information on reducing battery usage, see the Android training on <a + href="{@docRoot}training/monitoring-device-state/index.html">Optimizing + Battery Life</a>.</li> + </ul> + +<h3 class="rel-resources clearfloat">Related resources</h3> +<div class="resource-widget resource-flow-layout col-13" + data-query="collection:distribute/essentials/billionsquality/consumption" + data-sortOrder="-timestamp" + data-cardSizes="6x3" + data-maxResults="6"></div> + +<!-- content --> +<div class="headerLine"> + <h2 id="contentsection">Content</h2> +</div> +<p>Make sure that your app works well on a variety of screens: offering good, + crisp graphics and appropriate layouts on low resolution and physically small + screens. Ensure that your app is designed to be easily localized by + accommodating the variations between languages: allow for spacing, density, + order, emphasis, and wording variations. Also make sure that date, time, and + the like are internationalized and displayed according to the phone’s + settings.</p> + +<h3 id="content-responsive">Fast and responsive UI</h3> +<h4 id="content-feedback">Touch feedback on all touchable items</h4> + <ul> + <li>Touch feedback adds a tactile feeling to the user interface. You should + ensure your app provides touch feedback on all touchable elements to reduce + the perceived app latency as much as possible. +</li> + <li><a + href="https://www.google.com/design/spec/animation/responsive-interaction.html"> + Responsive interaction</a> encourages deeper exploration of an app by + creating timely, logical, and delightful screen reactions to user input. + Responsive interaction elevates an app from an information-delivery service + to an experience that communicates using multiple visual and tactile + responses.</li> + <li>For more information, see the Android training on <a + href="{@docRoot}training/material/animations.html#Touch">Customizing Touch + Feedback</a>.</li> + </ul> +<h4 id="content-interactive">UI should always be interactive</h4> + <ul> + <li>Apps that are unresponsive when performing background activity feel slow + and reduce user satisfaction. Ensure your app always has a responsive UI + regardless of any background activity. Achieve this by performing network + operations or any heavy-duty operations in a background thread—keep the UI + thread as idle as you can.</li> + <li>Material Design apps use minimal visual changes when your app is loading + content by representing each operation with a single activity indicator. + Avoid blocking dialogs with <a + href="https://www.google.com/design/spec/components/progress-activity.html"> + loading indicators</a>.</li> + <li><a + href="http://www.google.com/design/spec/patterns/empty-states.html">Empty + states</a> occur when the regular content of a view can’t be shown. It might + be a list that has no items or a search that returns no results. Avoid + completely empty states. The most basic empty state displays a + non-interactive image and a text tagline. Where you don’t have an image, or + the image is still loading, you should always show either a static + placeholder, or create a dynamic placeholder by using the <a + href="{@docRoot}tools/support-library/features.html#v7-palette">Palette + library</a> to generate placeholder colors that match the target image.</li> + <li>For more information, see the Android training on <a + href="{@docRoot}training/articles/perf-anr.html">Keeping Your App + Responsive</a>.</li> + </ul> +<h4 id="content-60fps">Target 60 frames per second on low-cost devices</h4> + <ul> + <li>Ensure that your app always runs fast and smoothly, even on low-cost + devices.</li> + <li>Overdraw can significantly slow down your app—it occurs when the pixels + are being drawn more than once per pass. An example of this is when you have + an image with a button placed on top of it. While some overdraw is + unavoidable, it should be minimized to ensure a smooth frame rate. Perform + <a href="{@docRoot}tools/performance/debug-gpu-overdraw/index.html">Debug + GPU overdraw</a> on your app to ensure it is minimized.</li> + <li>Android devices refresh the screen at 60 frames per second (fps), meaning + your app has to update the screen within roughly 16 milliseconds. <a + href="{@docRoot}tools/performance/profile-gpu-rendering/index.html">Profile + your app</a> using on-device tools to see if and when your app is not + meeting this 16-ms average.</li> + <li>Reduce or remove animations on low-cost devices to lessen the burden on + the device’s CPU and GPU. For more information, see the Android training on + <a href="{@docRoot}training/improving-layouts/index.html">Improving Layout + Performance</a>. </li> + </ul> +<h4 id="content-firstload">If anticipated start speed is low, use launch screen +on first load</h4> + <ul> + <li>The launch screen is a user’s first experience of your application. + Launching your app while displaying a blank canvas increases its perceived + loading time, so consider using a placeholder UI or a branded launch screen + to reduce the perceived loading time.</li> + <li>A<a href="https://www.google.com/design/spec/patterns/launch-screens.html#launch-screens-types-of-launch-screens"> + placeholder UI</a> is the most seamless launch transition, appropriate for + both app launches and in-app activity transitions.</li> + <li><a + href="https://www.google.com/design/spec/patterns/launch-screens.html#launch-screens-placeholder-ui"> + Branded launch screens</a> provide momentary brand exposure, freeing the UI + to focus on content.</li> + <li>For more information on implementing splash screens, see the <a + href="https://www.google.com/design/spec/patterns/launch-screens.html"> + Launch screens</a> section of the Material Design spec.</li> + </ul> +<h3 id="ui">UI best practices</h3> + <ul> + <li><a + href="https://www.google.com/design/spec/material-design/introduction.html"> + Material Design</a> is a visual language that synthesizes the classic + principles of good design with the innovation and possibility of technology + and science. Material Design aims to develop a single underlying system that + allows for a unified experience across platforms and device sizes. Consider + using key Material Design components so that users intuitively know how to + use your app.</li> + <li>Ready-to-use Material Design components are available via the <a + href="{@docRoot}tools/support-library/features.html#design">Design Support + library</a>. These components are supported in Android 2.1 (API level 7) and + above.</li> + </ul> +<h3 id="localization">Localization</h3> + <ul> + <li>Your users could be from any part of the world and their first language + may not be yours. If you don’t present your app in a language that your + users can read, it is a missed opportunity. You should therefore + localize your app for key regional languages.</li> + <li>To learn more, visit the Android training on <a + href="{@docRoot}training/basics/supporting-devices/languages.html"> + Supporting Different Languages</a>.</li> + </ul> + +<h3 class="rel-resources clearfloat">Related resources</h3> +<div class="resource-widget resource-flow-layout col-13" + data-query="collection:distribute/essentials/billionsquality/content" + data-sortOrder="-timestamp" + data-cardSizes="6x3" + data-maxResults="6"></div> diff --git a/docs/html/distribute/images/billions-guidelines.png b/docs/html/distribute/images/billions-guidelines.png Binary files differnew file mode 100644 index 000000000000..05f71b6eabd9 --- /dev/null +++ b/docs/html/distribute/images/billions-guidelines.png diff --git a/docs/html/jd_extras_en.js b/docs/html/jd_extras_en.js index 39a7e72f0a37..bd1803ab5866 100644 --- a/docs/html/jd_extras_en.js +++ b/docs/html/jd_extras_en.js @@ -277,6 +277,18 @@ METADATA['en'].extras = METADATA['en'].extras.concat([ "type":"medium" }, { + "title":"SmallerAPK, Part 6: Image optimization, Zopfli & WebP", + "category":"", + "summary":"Series of posts on minimizing your APK size.", + "url":"https://medium.com/@wkalicinski/smallerapk-part-6-image-optimization-zopfli-webp-4c462955647d#.23hlddo3x", + "group":"", + "keywords": [], + "tags": [], + "image":"https://cdn-images-1.medium.com/max/2000/1*chMiA9mGa_FBUOoesHHk3Q.png", + "type":"medium" + }, + + { "title":"Measure your app’s user acquisition channels", "category":"google", "summary":"Get details on how to use the Developer Console User Acquisitions reports to discover where your users come from.", @@ -1162,6 +1174,20 @@ METADATA['en'].extras = METADATA['en'].extras.concat([ "lang": "en", "group": "", "tags": [], + "url": "training/material/animations.html#Touch", + "timestamp": 1194884220000, + "image": null, + "title": "Customize Touch Feedback", + "summary": "Provide visual confirmation when users interact with your UI.", + "keywords": [], + "type": "develop", + "category": "guide" + }, + + { + "lang": "en", + "group": "", + "tags": [], "url": "guide/topics/manifest/uses-feature-element.html#testing", "timestamp": 1194884220000, "image": null, @@ -3825,6 +3851,7 @@ METADATA['en'].collections = { "distribute/essentials/quality/tv.html", "distribute/essentials/quality/wear.html", "distribute/essentials/quality/auto.html", + "distribute/essentials/quality/billions.html", "https://developers.google.com/edu/guidelines" ] }, @@ -3946,6 +3973,7 @@ METADATA['en'].collections = { "distribute/essentials/quality/wear.html", "distribute/essentials/quality/tv.html", "distribute/essentials/quality/auto.html", + "distribute/essentials/quality/billions.html", "https://developers.google.com/edu/guidelines" ] }, @@ -4403,6 +4431,44 @@ METADATA['en'].collections = { "distribute/tools/promote/device-art.html" ] }, + "distribute/essentials/billionsquality/connectivity": { + "title": "", + "resources": [ + "training/basics/network-ops/managing.html", + "training/monitoring-device-state/connectivity-monitoring.html", + "guide/topics/providers/content-providers.html" + ] + }, + "distribute/essentials/billionsquality/capability": { + "title": "", + "resources": [ + "guide/practices/screens_support.html", + "training/multiscreen/screendensities.html", + "training/articles/memory.html" + ] + }, + "distribute/essentials/billionsquality/cost": { + "title": "", + "resources": [ + "https://medium.com/@wkalicinski/smallerapk-part-4-multi-apk-through-abi-and-density-splits-477083989006#.23hlddo3x", + "training/basics/network-ops/managing.html" + ] + }, + "distribute/essentials/billionsquality/consumption": { + "title": "", + "resources": [ + "training/efficient-downloads/efficient-network-access.html", + "training/monitoring-device-state/index.html" + ] + }, + "distribute/essentials/billionsquality/content": { + "title": "", + "resources": [ + "training/material/animations.html#Touch", + "training/articles/perf-anr.html", + "training/improving-layouts/index.html" + ] + }, "distribute/getusers/notifications": { "title": "", "resources": [ |