| page.title=Multiple APK Support |
| |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| <h2>Quickview</h2> |
| <ul> |
| <li>Simultaneously publish different APKs for different |
| device configurations</li> |
| <li>You should publish multiple APKs only when it's not possible to |
| support all desired devices with a single APK</li> |
| </ul> |
| |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#Concepts">Publishing Concepts</a> |
| <ol> |
| <li><a href="#Active">Active APKs</a></li> |
| <li><a href="#SimpleAndAdvanced">Simple mode and advanced mode</a></li> |
| </ol> |
| </li> |
| <li><a href="#HowItWorks">How Multiple APKs Work</a> |
| <ol> |
| <li><a href="#SupportedFilters">Supported filters</a></li> |
| <li><a href="#Rules">Rules for multiple APKs</a></li> |
| </ol> |
| </li> |
| <li><a href="#CreatingApks">Creating Multiple APKs</a> |
| <ol> |
| <li><a href="#VersionCodes">Assigning version codes</a></li> |
| </ol> |
| </li> |
| <li><a href="#SingleAPK">Using a Single APK Instead</a> |
| <ol> |
| <li><a href="#TextureOptions">Supporting multiple GL textures</a></li> |
| <li><a href="#ScreenOptions">Supporting multiple screens</a></li> |
| <li><a href="#ApiLevelOptions">Supporting multiple API levels</a></li> |
| <li><a href="#CpuArchOptions">Supporting multiple CPU architectures</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>See also</h2> |
| <ol> |
| <li><a href="{@docRoot}google/play/expansion-files.html">APK Expansion Files</a></li> |
| <li><a href="{@docRoot}google/play/filters.html">Filters on Google Play</a></li> |
| <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li> |
| <li><a href="{@docRoot}tools/support-library/index.html">Support Library</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Android API Levels</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| <p>Multiple APK support is a feature on Google Play that allows you to publish different APKs |
| for your application that are each targeted to different device configurations. Each APK is a |
| complete and independent version of your application, but they share the same application listing on |
| Google Play and must share the same package name and be signed with the same release key. This |
| feature is useful for cases in which your application cannot reach all desired devices with a single |
| APK.</p> |
| |
| <p>Android-powered devices may differ in several ways and it's important |
| to the success of your application that you make it available to as many devices as possible. |
| Android applications usually run on most compatible devices with a single APK, by supplying |
| alternative resources for different configurations (for example, different layouts for different |
| screen sizes) and the Android system selects the appropriate resources for the device at runtime. In |
| a few cases, however, a single APK is unable to support all device configurations, because |
| alternative resources make the APK file too big (greater than 50MB) or other technical challenges |
| prevent a single APK from working on all devices.</p> |
| |
| <p>Although <strong>we encourage you to develop and publish a single APK</strong> that supports as |
| many device configurations as possible, doing so is sometimes not possible. To help |
| you publish your application for as many devices as possible, Google Play allows you to |
| publish multiple APKs under the same application listing. Google Play then supplies each APK to |
| the appropriate devices based on configuration support you've declared in the manifest file of each |
| APK. </p> |
| |
| <p>By publishing your application with multiple APKs, you can:</p> |
| |
| <ul> |
| <li>Support different OpenGL texture compression formats with each APK.</li> |
| <li>Support different screen sizes and densities with each APK.</li> |
| <li>Support different platform versions with each APK.</li> |
| <li>Support different CPU architectures with each APK (such as for ARM, x86, and MIPS, when your |
| app uses the <a href="{@docRoot}tools/sdk/ndk/index.html">Android NDK</a>).</li> |
| </ul> |
| |
| <p>Currently, these are the only device characteristics that Google Play supports for publishing |
| multiple APKs as the same application.</p> |
| |
| <p class="note"><strong>Note:</strong> You should generally use multiple APKs to support |
| different device configurations <strong>only when your APK is too large</strong> (greater than |
| 50MB) due to the alternative resources needed for different device configurations. |
| Using a single APK to support different configurations is always the best practice, |
| because it makes the path for application updates simple and clear for users (and also makes |
| your life simpler by avoiding development and publishing complexity). Read the section below about |
| <a href="#SingleAPK">Using a Single APK Instead</a> to |
| consider your options before publishing multiple APKs.</p> |
| |
| |
| <h2 id="Concepts">Publishing Concepts</h2> |
| |
| <p>Before you start publishing multiple APKs on Google Play, you must understand a few |
| concepts regarding how the Google Play Developer Console works.</p> |
| |
| <h3 id="Active">Active APKs</h3> |
| |
| <div class="sidebox-wrapper"> |
| <div class="sidebox"> |
| <h4>The difference between "Publish" and "Save"</h4> |
| <p>When editing your application, there are two buttons on the top-right side of the page. The |
| first button is either <strong>Publish</strong> or <strong>Unpublish</strong> and the second |
| button is always <strong>Save</strong> (but its behavior changes).</p> |
| <p>When your application is new or you have unpublished it from Google Play, the first |
| button says <strong>Publish</strong>. Clicking it will publish any APKs listed as |
| Active, making them available on Google Play. Also while your application is new |
| or unpublished, clicking <strong>Save</strong> will save any changes you've made, such |
| as information added to the Product details and APKs you've uploaded, but nothing is made visible on |
| Google Play—this allows you to save your changes and sign out of the Developer Console before |
| deciding to publish.</p> |
| <p>Once you've published your application, the first button changes to |
| <strong>Unpublish</strong>. Clicking it in this state unpublishes your application so that none |
| of the APKs are available on Google Play. Also while published, the behavior of the |
| <strong>Save</strong> button is different. In this state, clicking <strong>Save</strong> not |
| only saves all your changes, but also publishes them to Google Play. For example, if you've |
| already published your application and then make changes to your product details or activate new |
| APKs, clicking <strong>Save</strong> makes all those changes live on Google Play.</p> |
| </div> |
| </div> |
| |
| |
| <p>Before you can publish your application (whether publishing one or multiple APKs), you |
| must "activate" your APK(s) from the <strong>APK files</strong> tab. When you activate an APK, it |
| moves into the list of <em>Active</em> APKs. This list allows you to preview which APK(s) |
| you're about to publish.</p> |
| |
| <p>If there are no errors, any "active" APK will be published to |
| Google Play when you click the <strong>Publish</strong> button (if the application is |
| unpublished) or when you click the <strong>Save</strong> button (if the application is |
| already published).</p> |
| |
| |
| <h3 id="SimpleAndAdvanced">Simple mode and advanced mode</h3> |
| |
| <p>The Google Play Developer Console provides two modes for managing the APKs associated with |
| your application: <em>simple mode</em> and <em>advanced mode</em>. You can switch between these by |
| clicking the |
| link at the top-right corner of the <strong>APK files</strong> tab.</p> |
| |
| <p>Simple mode is the traditional way to publish an application, using one APK at a time. In |
| simple mode, only one APK can be activated at a time. If you upload a new APK to update |
| the application, clicking "Activate" on the new APK deactivates the currently |
| active APK (you must then click <strong>Save</strong> to publish the new APK).</p> |
| |
| <p>Advanced mode allows you to activate and publish multiple APKs that are each designed for a |
| specific set of device configurations. However, there are several rules based on the manifest |
| declarations in each APK that determine whether you're allowed to activate each APK along with |
| others. When you activate an APK and it violates one of the rules, you will receive an error or |
| warning message. If it's an error, you cannot publish until you resolve the problem; if it's a |
| warning, you can publish the activated APKs, but there might be unintended consequences as to |
| whether your application is available for different devices. These rules are discussed more |
| below.</p> |
| |
| |
| <h2 id="HowItWorks">How Multiple APKs Work</h2> |
| |
| <p>The concept for using multiple APKs on Google Play is that you have just one entry in |
| Google Play for your application, but different devices might download a different APK. This |
| means that:</p> |
| |
| <ul> |
| <li>You maintain only one set of product details (app description, icons, screenshots, etc.). |
| This also means you <em>cannot</em> charge a different price for different APKs.</li> |
| <li>All users see only one version of your application on Google Play, so they are not |
| confused by different versions you may have published that are "for tablets" or |
| "for phones."</li> |
| <li>All user reviews are applied to the same application listing, even though users on different |
| devices may have different APKs.</li> |
| <li>If you publish different APKs for different versions of Android (for different API levels), |
| then when a user's device receives a system update that qualifies them for a different APK you've |
| published, Google Play updates the user's application to the APK designed for the higher version |
| of Android. Any system data associated with the application is retained (the same as with normal |
| application updates when using a single APK).</li> |
| </ul> |
| |
| <p>To publish multiple APKs for the same application, you must enable <strong>Advanced mode</strong> |
| in your application's <strong>APK files</strong> tab (as discussed in the previous section). Once |
| in advanced mode, you can upload, activate, then publish multiple APKs for the same application. The |
| following sections describe more about how it works.</p> |
| |
| |
| <h3 id="SupportedFilters">Supported filters</h3> |
| |
| <p>Which devices receive each APK is determined by <a |
| href="{@docRoot}google/play/filters.html">Google Play filters</a> that are specified by |
| elements in the manifest file of each APK. However, Google Play allows you to publish multiple |
| APKs only when each APK uses filters to support a variation of the following |
| device characteristics:</p> |
| |
| <ul> |
| <li><strong>OpenGL texture compression formats</strong> |
| <p>This is based on your manifest file's <a |
| href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">{@code |
| <supports-gl-texture>}</a> element(s).</p> |
| <p>For example, when developing a game that uses OpenGL ES, you can provide one APK for |
| devices that support ATI texture compression and a separate APK for devices |
| that support PowerVR compression (among many others).</p> |
| <br/> |
| </li> |
| |
| <li><strong>Screen size (and, optionally, screen density)</strong> |
| <p>This is based on your manifest file's <a |
| href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code |
| <supports-screens>}</a> <em>or</em> <a |
| href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code |
| <compatible-screens>}</a> element. You should never use both elements and you should use only |
| <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code |
| <supports-screens>}</a> when possible.</p> |
| <p>For example, you can provide one APK that supports small and normal size screens and another |
| APK that supports large and xlarge screens.</p> |
| |
| <p class="note"><strong>Note:</strong> The Android system provides strong support for |
| applications to support all screen configurations with a single APK. You should avoid creating |
| multiple APKs to support different screens unless absolutely necessary and instead follow the guide |
| to <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple |
| Screens</a> so that your application is flexible and can adapt to all screen configurations |
| with a single APK.</p> |
| <p class="caution"><strong>Caution:</strong> By default, all screen size attributes in the <a |
| href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code |
| <supports-screens>}</a> element are "true" if you do not declare them otherwise. However, |
| because the {@code android:xlargeScreens} attribute was added in Android 2.3 (API level |
| 9), Google Play will assume that it is "false" if your application does not set either <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code |
| android:minSdkVersion}</a> or <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code |
| android:targetSdkVersion}</a> to "9" or higher.</p> |
| <p class="caution"><strong>Caution:</strong> You should not combine both <a |
| href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code |
| <supports-screens>}</a> and <a |
| href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code |
| <compatible-screens>}</a> elements in your manifest file. Using both increases the chances |
| that you'll introduce an error due to conflicts between them. For help deciding which to use, read |
| <a href="{@docRoot}guide/practices/screens-distribution.html">Distributing to Specific Screens</a>. |
| If you can't avoid using both, be aware that for any conflicts in agreement between a given size, |
| "false" will win.</p> |
| <br/> |
| </li> |
| |
| <li><strong>API level</strong> |
| <p>This is based on your manifest file's <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element. |
| You |
| can use both the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code |
| android:minSdkVersion}</a> and <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#max">{@code android:maxSdkVersion}</a> |
| attributes to specify support for different API levels.</p> |
| <p>For example, you can publish your application with one APK that supports API levels 4 - 7 |
| (Android 1.6 - 2.1)—using only APIs available since API level 4 or lower—and another |
| APK that supports API levels 8 and above (Android 2.2+)—using APIs available since API level 8 |
| or lower.</p> |
| <div class="note"> |
| <p><strong>Note:</strong></p> |
| <ul> |
| <li>If you use this characteristic as the factor to distinguish multiple APKs, then the APK |
| with a higher <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code |
| android:minSdkVersion}</a> value must have a higher <a |
| href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code android:versionCode}</a> |
| value. This is also true if two APKs overlap their device support based on a different supported |
| filter. This ensures that when a device receives a system update, Google Play can offer the user |
| an update for your application (because updates are based on an increase in the app version code). |
| This requirement is described further in the section below about <a href="#Rules">Rules for |
| multiple APKs</a>.</li> |
| <li>You should avoid using <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#max">{@code |
| android:maxSdkVersion}</a> in general, because as long as you've properly developed your |
| application with public APIs, it is always compatible with future versions of Android. If you want |
| to publish a different APK for higher API levels, you still do not need to specify the |
| maximum version, because if the <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code |
| android:minSdkVersion}</a> is {@code "4"} in one APK and {@code "8"} in another, devices that |
| support API level 8 or higher will always receive the second APK (because it's version code is |
| higher, as per the previous note).</li> |
| </ul> |
| </div> |
| </li> |
| |
| <li><strong>CPU architecture (ABI)</strong> |
| <p>This is based on the native libraries included in each APK (which are |
| determined by the architectures you declare in the {@code Application.mk} |
| file) when using the Android NDK.</p></li> |
| </ul> |
| |
| <p>Other manifest elements that enable <a |
| href="{@docRoot}google/play/filters.html">Google Play filters</a>—but are not |
| listed above—are still applied for each APK as usual. However, Google Play does not allow |
| you to publish separate APKs based on variations of those device characteristics. Thus, you cannot |
| publish multiple APKs if the above listed filters are the same for each APK (but the APKs differ |
| based on other characteristics in the manifest or APK). For |
| example, you cannot provide different APKs that differ purely on the <a |
| href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">{@code |
| <uses-configuration>}</a> characteristics.</p> |
| |
| |
| |
| <h3 id="Rules">Rules for multiple APKs</h3> |
| |
| <p>Before you enable advanced mode to publish multiple APKs for your application, you need to |
| understand the following rules that define how publishing multiple APKs works:</p> |
| |
| <ul> |
| <li>All APKs you publish for the same application <strong>must have the same package |
| name and be signed with the same certificate key</strong>.</li> |
| |
| <li>Each APK <strong>must have a different version code</strong>, specified by the |
| <a href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code |
| android:versionCode}</a> attribute.</li> |
| |
| <li>Each APK <strong>must not exactly match the configuration support of another APK</strong>. |
| <p>That is, each APK must declare slightly different support for at least one of |
| the <a href="#SupportedFilters">supported Google Play filters</a> (listed above).</p> |
| <p>Usually, you will differentiate your APKs based on a specific characteristic (such as the |
| supported texture compression formats), and thus, each APK will declare support for different |
| devices. However, it's OK to publish multiple APKs that overlap their support slightly. When two |
| APKs do overlap (they support some of the same device configurations), a device that falls within |
| that overlap range will receive the APK with a higher version code (defined by <a |
| href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code |
| android:versionCode}</a>).</p></li> |
| |
| <li>You cannot activate a new APK that has a version code lower than that of the APK it's |
| replacing. For example, say you have an active APK for screen sizes small - normal with version code |
| 0400, then try to replace it with an APK for the same screen sizes with version code 0300. This |
| raises an error, because it means users of the previous APK will not be able to update the |
| application.</li> |
| |
| <li>An APK that requires a <strong>higher API level</strong> must have a <strong>higher |
| version code</strong>. |
| <p>This is true only when either: the APKs differ based <em>only</em> on the |
| supported API levels (no other <a href="#SupportedFilters">supported filters</a> |
| distinguish the APKs from each other) <em>or</em> when the APKs do use another supported filter, but |
| there is an overlap between the APKs within that filter.</p> |
| <p>This is important because a user's device receives an application update from |
| Google Play only if the version code for the APK on Google Play is higher than the version |
| code of the APK currently on the device. This ensures that if a device receives a system update that |
| then qualifies it to install the APK for higher API levels, the device receives an application |
| update because the version code increases.</p> |
| <p class="note"><strong>Note:</strong> The size of the version code increase is irrelevant; it |
| simply needs to be larger in the version that supports higher API levels.</p> |
| <p>Here are some examples:</p> |
| <ul> |
| <li>If an APK you've uploaded for API levels 4 and above (Android 1.6+) has a version code of |
| {@code 0400}, then an APK for API levels 8 and above (Android 2.2+) must be {@code 0401} or |
| greater. In this case, the API level is the only supported filter used, so the version codes |
| <strong>must increase</strong> in correlation with the API level support for each APK, so that users |
| get an update when they receive a system update.</li> |
| <li>If you have one APK that's for API level 4 (and above) <em>and</em> small - |
| large screens, and another APK for API level 8 (and above) <em>and</em> large - xlarge screens, then |
| the version codes <strong>must increase</strong> in correlation with the API levels. |
| In this case, the API level filter is used to |
| distinguish each APK, but so is the screen size. Because the screen sizes overlap (both APKs |
| support large screens), the version codes must still be in order. This ensures that a large screen |
| device that receives a system update to API level 8 will receive an update for the second |
| APK.</li> |
| <li>If you have one APK that's for API level 4 (and above) <em>and</em> small - |
| normal screens, and another APK for API level 8 (and above) <em>and</em> large - xlarge |
| screens, then the version codes <strong>do not need to increase</strong> in correlation with the API |
| levels. Because there is no overlap within the screen size filter, there are no devices that |
| could potentially move between these two APKs, so there's no need for the version codes to |
| increase from the lower API level to the higher API level.</li> |
| <li>If you have one APK that's for API level 4 (and above) <em>and</em> ARMv7 CPUs, |
| and another APK for API level 8 (and above) <em>and</em> ARMv5TE CPUs, |
| then the version codes <strong>must increase</strong> in correlation with the API levels. |
| In this case, the API level filter is used to |
| distinguish each APK, but so is the CPU architecture. Because an APK with ARMv5TE libraries is |
| compatible with devices that have an ARMv7 CPU, the APKs overlap on this characteristic. |
| As such, the version code for the APK that supports API level 8 and above must be higher. |
| This ensures that a device with an ARMv7 CPU that receives a system update to API level 8 |
| will receive an update for the second APK that's designed for API level 8. |
| However, because this kind of update results in the ARMv7 device using an APK that's not |
| fully optimized for that device's CPU, you should provide an |
| APK for both the ARMv5TE and the ARMv7 architecture at each API level in order to optimize |
| the app performance on each CPU. |
| <strong>Note:</strong> This applies <em>only</em> when comparing APKs with the ARMv5TE and |
| ARMv7 libraries, and not when comparing other native libraries.</li> |
| </ul> |
| </li> |
| |
| </ul> |
| |
| <p>Failure to abide by the above rules results in an error on the Google Play Developer Console |
| when you activate your APKs—you will be unable to publish your application until you |
| resolve the error.</p> |
| |
| <p>There are other conflicts that might occur when you activate your APKs, but which will result |
| in warnings rather than errors. Warnings can be caused by the following:</p> |
| |
| <ul> |
| <li>When you modify an APK to "shrink" the support for a device's characteristics and no other |
| APKs support the devices that then fall outside the supported range. For example, if an APK |
| currently supports small and normal size screens and you change it to support only small screens, |
| then you have shrunk the pool of supported devices and some devices will no longer see your |
| application on Google Play. You can resolve this by adding another APK that supports normal size |
| screens so that all previously-supported devices are still supported.</li> |
| |
| <li>When there are "overlaps" between two or more APKs. For example, if an APK supports screen |
| sizes small, normal, and large, while another APK supports sizes large and xlarge, there is an |
| overlap, because both APKs support large screens. If you do not resolve this, then devices that |
| qualify for both APKs (large screen devices in the example) will receive whichever APK has the |
| highest version code. |
| <p class="note"><strong>Note:</strong> If you're creating separate APKs for different CPU |
| architectures, be aware that an APK for ARMv5TE will overlap with an APK for ARMv7. That is, |
| an APK designed for ARMv5TE is compatible with an ARMv7 device, |
| but the reverse is not true (an APK with only the ARMv7 libraries is |
| <em>not</em> compatible with an ARMv5TE device).</li> |
| </ul> |
| |
| <p>When such conflicts occur, you will see a warning message, but you can still publish your |
| application.</p> |
| |
| |
| |
| <h2 id="CreatingApks">Creating Multiple APKs</h2> |
| |
| <p>Once you decide to publish multiple APKs, you probably need to create separate |
| Android projects for each APK you intend to publish so that you can appropriately develop them |
| separately. You can do this by simply duplicating your existing project and give it a new name. |
| (Alternatively, you might use a build system that can output different resources—such |
| as textures—based on the build configuration.)</p> |
| |
| <p class="note"><strong>Tip:</strong> One way to avoid duplicating large portions of your |
| application code is to use a <a |
| href="{@docRoot}tools/projects/index.html#LibraryProjects">library project</a>. A library |
| project holds shared code and resources, which you can include in your actual application |
| projects.</p> |
| |
| <p>When creating multiple projects for the same application, it's a good practice to identify each |
| one with a name that indicates the device restrictions to be placed on the APK, so you can |
| easily identify them. For example, "HelloWorld_8" might be a good name for an |
| application designed for API level 8 and above.</p> |
| |
| <p class="note"><strong>Note:</strong> All APKs you publish for the same application |
| <strong>must have the same package name and be signed with the same certificate key</strong>. Be |
| sure you also understand each of the <a href="#Rules">Rules for multiple APKs</a>.</p> |
| |
| |
| <h3 id="VersionCodes">Assigning version codes</h3> |
| |
| <p>Each APK for the same application <strong>must have a unique version code</strong>, specified by |
| the <a href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code |
| android:versionCode}</a> attribute. You must be careful about assigning version codes when |
| publishing multiple APKs, because they must each be different, but in some |
| cases, must or should be defined in a specific order, based on the configurations that each APK |
| supports.</p> |
| |
| <h4>Ordering version codes</h4> |
| |
| <p>An APK that requires a higher API level must usually have a higher version code. For example, if |
| you create two APKs to support different API levels, the APK for the higher API levels must have the |
| higher version code. This ensures that if a device receives a system update that then qualifies it |
| to install the APK for higher API levels, the user receives a notification to update the app. For |
| more information about how this requirement applies, see the section above about <a |
| href="#Rules">Rules for multiple APKs</a>.</p> |
| |
| <p>You should also consider how the order of version codes might affect which APK your users |
| receive either due to overlap between coverage of different APKs or future changes you might make to |
| your APKs.</p> |
| |
| <p>For example, if you have different APKs based on screen size, such as one for small - normal and |
| one for large - xlarge, but foresee a time when you will change the APKs to be one for small and one |
| for normal - xlarge, then you should make the version code for the large - xlarge APK be higher. |
| That way, a normal size device will receive the appropriate update when you make the change, because |
| the version code increases from the existing APK to the new APK that now supports the device. </p> |
| |
| <p>Also, when creating multiple APKs that differ based on support for different OpenGL texture |
| compression formats, be aware that many devices support multiple formats. Because a device |
| receives the APK with the highest version code when there is an overlap in coverage between two |
| APKs, you should order the version codes among your APKs so that the APK with the |
| preferred compression format has the highest version code. For example, you might want to perform |
| separate builds for your app using PVRTC, ATITC, and ETC1 compression formats. If you prefer these |
| formats in this exact order, then the APK that uses PVRTC should have the highest version code, the |
| APK that uses ATITC has a lower version code, and the version with ETC1 has the lowest. Thus, if a |
| device supports both PVRTC and ETC1, it receives the APK with PVRTC, because it has the highest |
| version code.</p> |
| |
| |
| <h4>Using a version code scheme</h4> |
| |
| <p>In order to allow different APKs to update their version codes independent of others (for |
| example, when you fix a bug in only one APK, so don't need to update all APKs), you should use a |
| scheme for your version codes that |
| provides sufficient room between each APK so that you can increase the code in one without requiring |
| an increase in others. You should also include your actual version name in the code (that is, the |
| user visible version assigned to <a |
| href="{@docRoot}guide/topics/manifest/manifest-element.html#vname">{@code android:versionName}</a>), |
| so that it's easy for you to associate the version code and version name.</p> |
| |
| <p class="note"><strong>Note:</strong> When you increase the version code for an APK, Google |
| Play will prompt users of the previous version to update the application. Thus, to avoid |
| unnecessary updates, you should not increase the version code for APKs that do not actually |
| include changes.</p> |
| |
| <p>We suggest using a version code with at least 7 digits: integers that represent |
| the supported configurations are in the higher order bits, and the version name (from <a |
| href="{@docRoot}guide/topics/manifest/manifest-element.html#vname">{@code |
| android:versionName}</a>) is in the lower order bits. For example, when the application version |
| name is 3.1.0, version codes for an API level 4 |
| APK and an API level 11 APK would be something like 0400310 and 1100310, respectively. The first |
| two digits are reserved for the API Level (4 and 11, respectively), the middle two digits are for |
| either screen sizes or GL texture formats (not used in these examples), and the last three digits |
| are for the application's version name (3.1.0). Figure 1 shows two examples that split based on both |
| the platform version (API Level) and screen size.</p> |
| |
| <img src="{@docRoot}images/market/version-codes.png" alt="" /> |
| <p class="img-caption"><strong>Figure 1.</strong> A suggested scheme for your version codes, |
| using the first two digits for the API Level, the second and third digits for the minimum and |
| maximum screen size (1 - 4 indicating each of the four sizes) or to denote the texture formats |
| and the last three digits for the app version.</p> |
| |
| <p>This scheme for version codes is just a suggestion for how you should establish a |
| pattern that is scalable as your application evolves. In particular, this scheme doesn't |
| demonstrate a solution for identifying different texture compression formats. One option might be |
| to define your own table that specifies a different integer to each of the different |
| compression formats your application supports (for example, 1 might correspond to ETC1 and 2 is |
| ATITC, and so on).</p> |
| |
| <p>You can use any scheme you want, but you should carefully consider how future versions of your |
| application will need to increase their version codes and how devices can receive updates when |
| either the device configuration changes (for example, due to a system update) or when you modify the |
| configuration support for one or several of the APKs.</p> |
| |
| |
| |
| |
| <h2 id="SingleAPK">Using a Single APK Instead</h2> |
| |
| <p><strong>Creating multiple APKs for your application is not the normal procedure</strong> for |
| publishing an application on Google Play. In most cases, you should be able to publish your |
| application to most users with a single APK and we encourage that you do so. When you encounter |
| a situation in which using a single APK becomes difficult, you should carefully consider all your |
| options before deciding to publish multiple APKs.</p> |
| |
| <p>First of all, there are a few key benefits to developing a single APK that supports all |
| devices:</p> |
| |
| <ul> |
| <li><strong>Publishing and managing your application is easier.</strong> |
| <p>With only one APK to worry about at any given time, you're less likely to become confused by |
| which APK is what. You also don't have to keep track of multiple version codes for each |
| APK—by using only one APK, you can simply increase the version code with each release and |
| be done.</p> </li> |
| <li><strong>You need to manage only a single code base.</strong> |
| <p>Although you can use a <a |
| href="{@docRoot}tools/projects/index.html#LibraryProjects">library project</a> |
| to share code between multiple Android projects, it's still likely that you'll reproduce some code |
| across each project and this could become difficult to manage, especially when resolving |
| bugs.</p></li> |
| <li><strong>Your application can adapt to device configuration changes.</strong> |
| <p>By creating a single APK that contains all the resources for each device configuration, your |
| application can adapt to configuration changes that occur at runtime. For example, if the user docks |
| or otherwise connects a handset device to a larger screen, there's a chance that this will invoke a |
| system configuration change to support the larger screen. If you include all resources for different |
| screen configurations in the same APK, then your application will load alternative resources and |
| optimize the user experience for the new interface.</p> |
| </li> |
| <li><strong>App restore across devices just works.</strong> |
| <p>If a user has enabled data backup on his or her current device and then buys a new device |
| that has a different configuration, then when the user's apps are automatically restored during |
| setup, the user receives your application and it runs using the resources optimized for that device. |
| For example, on a new tablet, the user receives your application and it runs with your |
| tablet-optimized resources. This restore |
| process does not work across different APKs, because each APK can potentially have different |
| permissions that the user has not agreed to, so Google Play may not restore the application at |
| all. (If you use multiple APKs, the user receives either the exact same APK if it's compatible or |
| nothing at all and must manually download your application to get the APK designed for the new |
| device.)</p></li> |
| </ul> |
| |
| <p>The following sections describe some of the other options you should use to support multiple |
| device configurations before deciding to publish multiple APKs.</p> |
| |
| |
| |
| <h3 id="TextureOptions">Supporting multiple GL textures</h3> |
| |
| <p>To support multiple types of GL textures with a single APK, your application should query the GL |
| texture formats supported on the device and then use the appropriate resources or download |
| them from a web server. For example, in order to keep the size of your APK small, you can query the |
| device's support for different GL texture formats when the application starts for the first time and |
| then download only the textures you need for that device.</p> |
| |
| <p>For maximum performance and compatibility, your application should use ETC1 textures wherever it |
| doesn't impact the visual quality. However, because ETC1 cannot deal with images that have drastic |
| chroma changes, such as line art and (most) text, and doesn't support alpha, it may not the best |
| format for all textures.</p> |
| |
| <p>With a single APK, you should try to use ETC1 textures and uncompressed textures whenever |
| reasonable, and consider the use of PVRTC, ATITC, or DXTC as a last resort when ETC1 does not |
| suffice.</p> |
| |
| <p>Here's an example query for supported texture compression formats from inside a |
| {@link android.opengl.GLSurfaceView.Renderer GLSurfaceView.Renderer}:</p> |
| |
| <pre> |
| public void onSurfaceChanged(GL10 gl, int w, int h) { |
| String extensions = gl.glGetString(GL10.GL_EXTENSIONS); |
| Log.d("ExampleActivity", extensions); |
| } |
| </pre> |
| |
| <p>This returns a string that lists each of the supported compression formats.</p> |
| |
| |
| |
| <h3 id="ScreenOptions">Supporting multiple screens</h3> |
| |
| <p>Unless your APK file exceeds the Google Play size limit of 50MB, supporting multiple screens |
| should always be done with a single APK. Since Android 1.6, the Android system manages most of the |
| work required for your application to run successfully on a variety of screen sizes and |
| densities.</p> |
| |
| <p>To further optimize your application for different screen sizes and densities, you should provide |
| <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">alternative |
| resources</a> such as bitmap drawables at different resolutions and different layout designs for |
| different screen sizes.</p> |
| |
| <p>For more information about how to support multiple screens with a single APK, read <a |
| href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.</p> |
| |
| <p>Additionally, you should consider using a support library from the <a |
| href="{@docRoot}tools/support-library/index.html">Compatibility Package</a> so that you can add <a |
| href="{@docRoot}guide/components/fragments.html">Fragments</a> to your activity designs |
| when running on larger screens such as tablets.</p> |
| |
| |
| |
| <h3 id="ApiLevelOptions">Supporting multiple API levels</h3> |
| |
| <p>If you want to support as many versions of the Android platform as possible, you should use |
| only APIs available in the lowest reasonable version. For example, your application may not require |
| APIs newer than Android 2.1 (API Level 7), which makes an application available to |
| over 95% of Android-powered devices (as indicated by the <a |
| href="{@docRoot}about/dashboards/index.html">Platform Versions</a> dashboard).</p> |
| |
| <p>By using a support library from the <a |
| href="{@docRoot}tools/support-library/index.html">Compatibility Package</a>, you can also use APIs |
| from some of the latest versions (such as Android 3.0) while |
| still supporting versions as low as Android 1.6. The support library includes APIs for <a |
| href="{@docRoot}guide/components/fragments.html">Fragments</a>, <a |
| href="{@docRoot}guide/components/loaders.html">Loaders</a>, and more. Using the fragment |
| APIs is particularly valuable so that you can optimize your user interface for large devices such as |
| tablets.</p> |
| |
| <p>Alternatively, if you want to use some APIs that are available only in newer versions of Android |
| (which your application can still function without), then you should consider using reflection. By |
| using reflection, you can check whether the current device supports certain APIs. If the APIs are |
| not available, your application can gracefully disable and hide the feature.</p> |
| |
| <p>Another way to use new APIs only when running on a version that supports them is to check the |
| API level of the current device. That is, you can query the value of {@link |
| android.os.Build.VERSION#SDK_INT} and create different code paths depending on the API level |
| supported by the device. For example:</p> |
| |
| <pre> |
| if (android.os.Build.VERSION.SDK_INT >= 11) { |
| // Use APIs supported by API level 11 (Android 3.0) and up |
| } else { |
| // Do something different to support older versions |
| } |
| </pre> |
| |
| |
| <h3 id="CpuArchOptions">Supporting multiple CPU architectures</h3> |
| |
| <p>When using the Android NDK, you can create a single APK that supports multiple CPU architectures |
| by declaring each of the desired architectures with the {@code APP_ABI} variable in the |
| <code>Application.mk</code> file.</p> |
| |
| <p>For example, here's an <code>Application.mk</code> file that declares support for three |
| different CPU architectures:</p> |
| |
| <pre> |
| APP_ABI := armeabi armeabi-v7a mips |
| APP_PLATFORM := android-9 |
| </pre> |