Multiple APK support is a feature in Android Market that allows you to publish different APKsfor your application that are each targeted to different device configurations. Each APK is acomplete and independent version of your application, but they share the same application listing onAndroid Market and must share the same package name and be signed with the same release key. Thisfeature is useful for cases in which your application cannot reach all desired devices with a singleAPK.
Android-powered devices may differ in several ways and it's importantto 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 supplyingalternative resources for different configurations (for example, different layouts for differentscreen sizes) and the Android system selects the appropriate resources for the device at runtime. Ina few cases, however, a single APK is unable to support all device configurations, becausealternative resources make the APK file too big (greater than 50MB) or other technical challengesprevent a single APK from working on all devices.
Although we encourage you to develop and publish a single APK that supports asmany device configurations as possible, doing so is sometimes not possible. To helpyou publish your application for as many devices as possible, Android Market allows you topublish multiple APKs under the same application listing. Android Market then supplies each APK tothe appropriate devices based on configuration support you've declared in the manifest file of eachAPK.
By publishing your application with multiple APKs, you can:
Currently, these are the only device characteristics that Android Market supports for publishingmultiple APKs as the same application.
Note: You should generally use multiple APKs to supportdifferent device configurations only when your APK is too large (greater than50MB). 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 makesyour life simpler by avoiding development and publishing complexity). Read the section below aboutUsing a Single APK Instead toconsider your options before publishing multiple APKs.
Before you start publishing multiple APKs on Android Market, you must understand a fewconcepts regarding how the Android Market publisher site works.
When editing your application, there are two buttons on the top-right side of the page. Thefirst button is either Publish or Unpublish and the secondbutton is always Save (but its behavior changes).
When your application is new or you have unpublished it from Market, the firstbutton says Publish. Clicking it will publish any APKs listed asActive, making them available on Android Market. Also while your application is newor unpublished, clicking Save will save any changes you've made, suchas information added to the Product details and APKs you've uploaded, but nothing is made visible onAndroid Market—this allows you to save your changes and sign out of the publisher site beforedeciding to publish.
Once you've published your application, the first button changes toUnpublish. Clicking it in this state unpublishes your application so that noneof the APKs are available on Android Market. Also while published, the behavior of theSave button is different. In this state, clicking Save notonly saves all your changes, but also publishes them to Android Market. For example, if you'vealready published your application and then make changes to your product details or activate newAPKs, clicking Save makes all those changes live on Android Market.
Before you can publish your application (whether publishing one or multiple APKs), youmust "activate" your APK(s) from the APK files tab. When you activate an APK, itmoves into the list of Active APKs. This list allows you to preview which APK(s)you're about to publish.
If there are no errors, any "active" APK will be published toAndroid Market when you click the Publish button (if the application isunpublished) or when you click the Save button (if the application isalready published).
The Android Market publisher site provides two modes for managing the APKs associated withyour application: simple mode and advanced mode. You can switch between these byclicking thelink at the top-right corner of the APK files tab.
Simple mode is the traditional way to publish an application, using one APK at a time. Insimple mode, only one APK can be activated at a time. If you upload a new APK to updatethe application, clicking "Activate" on the new APK deactivates the currentlyactive APK (you must then click Save to publish the new APK).
Advanced mode allows you to activate and publish multiple APKs that are each designed for aspecific set of device configurations. However, there are several rules based on the manifestdeclarations in each APK that determine whether you're allowed to activate each APK along withothers. When you activate an APK and it violates one of the rules, you will receive an error orwarning message. If it's an error, you cannot publish until you resolve the problem; if it's awarning, you can publish the activated APKs, but there might be unintended consequences as towhether your application is available for different devices. These rules are discussed morebelow.
The concept for using multiple APKs on Android Market is that you have just one entry inAndroid Market for your application, but different devices might download a different APK. Thismeans that:
To publish multiple APKs for the same application, you must enable Advanced modein your application's APK files tab (as discussed in the previous section). Oncein advanced mode, you can upload, activate, then publish multiple APKs for the same application. Thefollowing sections describe more about how it works.
Which devices receive each APK is determined by Android Market filters that are specified byelements in the manifest file of each APK. However, Android Market allows you to publish multipleAPKs only when each APK uses filters to support a variation of the followingdevice characteristics:
This is based on your manifest file's <supports-gl-texture>
element(s).
For example, when developing a game that uses OpenGL ES, you can provide one APK fordevices that support ATI texture compression and a separate APK for devicesthat support PowerVR compression (among many others).
This is based on your manifest file's <supports-screens>
or <compatible-screens>
element. You should never use both elements and you should use only<supports-screens>
when possible.
For example, you can provide one APK that supports small and normal size screens and anotherAPK that supports large and xlarge screens.
Note: The Android system provides strong support forapplications to support all screen configurations with a single APK. You should avoid creatingmultiple APKs to support different screens unless absolutely necessary and instead follow the guideto Supporting MultipleScreens so that your application is flexible and can adapt to all screen configurationswith a single APK.
Caution: By default, all screen size attributes in the <supports-screens>
element are "true" if you do not declare them otherwise. However,because the android:xlargeScreens
attribute was added in Android 2.3 (API level9), Android Market will assume that it is "false" if your application does not set either android:minSdkVersion
or android:targetSdkVersion
to "9" or higher.
Caution: You should not combine both <supports-screens>
and <compatible-screens>
elements in your manifest file. Using both increases the chancesthat you'll introduce an error due to conflicts between them. For help deciding which to use, readDistributing to Specific Screens.If you can't avoid using both, be aware that for any conflicts in agreement between a given size,"false" will win.
This is based on your manifest file's <uses-sdk>
element.Youcan use both the android:minSdkVersion
and android:maxSdkVersion
attributes to specify support for different API levels.
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 anotherAPK that supports API levels 8 and above (Android 2.2+)—using APIs available since API level 8or lower.
Note:
android:minSdkVersion
value must have a higher android:versionCode
value. This is also true if two APKs overlap their device support based on a different supportedfilter. This ensures that when a device receives a system update, Android Market can offer the useran 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 Rules formultiple APKs.android:maxSdkVersion
in general, because as long as you've properly developed yourapplication with public APIs, it is always compatible with future versions of Android. If you wantto publish a different APK for higher API levels, you still do not need to specify themaximum version, because if the android:minSdkVersion
is "4"
in one APK and "8"
in another, devices thatsupport API level 8 or higher will always receive the second APK (because it's version code ishigher, as per the previous note).Other manifest elements that enable Android Market filters—but are notlisted above—are still applied for each APK as usual. However, Android Market does not allowyou to publish multiple APKs based on variations of them. Thus, you cannot publishmultiple APKs if the above listed filters are the same for each APK (but the APKs differ based onother characteristics in the manifest file). Forexample, you cannot provide different APKs that differ purely on the <uses-configuration>
characteristics.
Before you enable advanced mode to publish multiple APKs for your application, you need tounderstand the following rules that define how publishing multiple APKs works:
android:versionCode
attribute.That is, each APK must declare slightly different support for at least one ofthe supported Market filters (listed above).
Usually, you will differentiate your APKs based on a specific characteristic (such as thesupported texture compression formats), and thus, each APK will declare support for differentdevices. However, it's OK to publish multiple APKs that overlap their support slightly. When twoAPKs do overlap (they support some of the same device configurations), a device that falls withinthat overlap range will receive the APK with a higher version code (defined by android:versionCode
).
This is true only when either: the APKs differ based only on thesupported API levels (no other supported market filtersdistinguish the APKs from each other) or when the APKs do use another supported filter, butthere is an overlap between the APKs within that filter.
This is important because a user's device receives an application update fromAndroid Market only if the version code for the APK on Android Market is higher than the versioncode of the APK currently on the device. This ensures that if a device receives a system update thatthen qualifies it to install the APK for higher API levels, the device receives an applicationupdate because the version code increases.
Note: The size of the version code increase is irrelevant; itsimply needs to be larger in the version that supports higher API levels.
Here are some examples:
0400
, then an APK for API levels 8 and above (Android 2.2+) must be 0401
orgreater. In this case, the API level is the only supported filter used, so the version codesmust increase in correlation with the API level support for each APK, so that usersget an update when they receive a system update.Failure to abide by the above rules results in an error on the Android Market publisher sitewhen you activate your APKs—you will be unable to publish your application until youresolve the error.
There are other conflicts that might occur when you activate your APKs, but which will resultin warnings rather than errors. Warnings can be caused by the following:
When such conflicts occur, you will see a warning message, but you can still publish yourapplication.
Once you decide to publish multiple APKs, you probably need to create separateAndroid projects for each APK you intend to publish so that you can appropriately develop themseparately. 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—suchas textures—based on the build configuration.)
Tip: One way to avoid duplicating large portions of yourapplication code is to use a library project. A libraryproject holds shared code and resources, which you can include in your actual applicationprojects.
When creating multiple projects for the same application, it's a good practice to identify eachone with a name that indicates the device restrictions to be placed on the APK, so you caneasily identify them. For example, "HelloWorld_8" might be a good name for anapplication designed for API level 8 and above.
Note: All APKs you publish for the same applicationmust have the same package name and be signed with the same certificate key. Besure you also understand each of the Rules for multiple APKs.
Each APK for the same application must have a unique version code, specified bythe android:versionCode
attribute. You must be careful about assigning version codes whenpublishing multiple APKs, because they must each be different, but in somecases, must or should be defined in a specific order, based on the configurations that each APKsupports.
An APK that requires a higher API level must usually have a higher version code. For example, ifyou create two APKs to support different API levels, the APK for the higher API levels must have thehigher version code. This ensures that if a device receives a system update that then qualifies itto install the APK for higher API levels, the user receives a notification to update the app. Formore information about how this requirement applies, see the section above about Rules for multiple APKs.
You should also consider how the order of version codes might affect which APK your usersreceive either due to overlap between coverage of different APKs or future changes you might make toyour APKs.
For example, if you have different APKs based on screen size, such as one for small - normal andone for large - xlarge, but foresee a time when you will change the APKs to be one for small and onefor 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, becausethe version code increases from the existing APK to the new APK that now supports the device.
Also, when creating multiple APKs that differ based on support for different OpenGL texturecompression formats, be aware that many devices support multiple formats. Because a devicereceives the APK with the highest version code when there is an overlap in coverage between twoAPKs, you should order the version codes among your APKs so that the APK with thepreferred compression format has the highest version code. For example, you might want to performseparate builds for your app using PVRTC, ATITC, and ETC1 compression formats. If you prefer theseformats in this exact order, then the APK that uses PVRTC should have the highest version code, theAPK that uses ATITC has a lower version code, and the version with ETC1 has the lowest. Thus, if adevice supports both PVRTC and ETC1, it receives the APK with PVRTC, because it has the highestversion code.
In order to allow different APKs to update their version codes independent of others (forexample, when you fix a bug in only one APK, so don't need to update all APKs), you should use ascheme for your version codes thatprovides sufficient room between each APK so that you can increase the code in one without requiringan increase in others. You should also include your actual version name in the code (that is, theuser visible version assigned to android:versionName
),so that it's easy for you to associate the version code and version name.
Note: When you increase the version code for an APK, AndroidMarket will prompt users of the previous version to update the application. Thus, to avoidunnecessary updates, you should not increase the version code for APKs that do not actuallyinclude changes.
We suggest using a version code with at least 7 digits: integers that representthe supported configurations are in the higher order bits, and the version name (from android:versionName
) is in the lower order bits. For example, when the application versionname is 3.1.0, version codes for an API level 4APK and an API level 11 APK would be something like 0400310 and 1100310, respectively. The firsttwo digits are reserved for the API Level (4 and 11, respectively), the middle two digits are foreither screen sizes or GL texture formats (not used in these examples), and the last three digitsare for the application's version name (3.1.0). Figure 1 shows two examples that split based on boththe platform version (API Level) and screen size.
This scheme for version codes is just a suggestion for how you should establish apattern that is scalable as your application evolves. In particular, this scheme doesn'tdemonstrate a solution for identifying different texture compression formats. One option might beto define your own table that specifies a different integer to each of the differentcompression formats your application supports (for example, 1 might correspond to ETC1 and 2 isATITC, and so on).
You can use any scheme you want, but you should carefully consider how future versions of yourapplication will need to increase their version codes and how devices can receive updates wheneither the device configuration changes (for example, due to a system update) or when you modify theconfiguration support for one or several of the APKs.
Creating multiple APKs for your application is not the normal procedure forpublishing an application on Android Market. In most cases, you should be able to publish yourapplication to most users with a single APK and we encourage that you do so. When you encountera situation in which using a single APK becomes difficult, you should carefully consider all youroptions before deciding to publish multiple APKs.
First of all, there are a few key benefits to developing a single APK that supports alldevices:
With only one APK to worry about at any given time, you're less likely to become confused bywhich APK is what. You also don't have to keep track of multiple version codes for eachAPK—by using only one APK, you can simply increase the version code with each release andbe done.
Although you can use a library projectto share code between multiple Android projects, it's still likely that you'll reproduce some codeacross each project and this could become difficult to manage, especially when resolvingbugs.
By creating a single APK that contains all the resources for each device configuration, yourapplication can adapt to configuration changes that occur at runtime. For example, if the user docksor otherwise connects a handset device to a larger screen, there's a chance that this will invoke asystem configuration change to support the larger screen. If you include all resources for differentscreen configurations in the same APK, then your application will load alternative resources andoptimize the user experience for the new interface.
If a user has enabled data backup on his or her current device and then buys a new devicethat has a different configuration, then when the user's apps are automatically restored duringsetup, 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 yourtablet-optimized resources. This restoreprocess does not work across different APKs, because each APK can potentially have differentpermissions that the user has not agreed to, so Android Market may not restore the application atall. (If you use multiple APKs, the user receives either the exact same APK if it's compatible ornothing at all and must manually download your application to get the APK designed for the newdevice.)
The following sections describe some of the other options you should use to support multipledevice configurations before deciding to publish multiple APKs.
To support multiple types of GL textures with a single APK, your application should query the GLtexture formats supported on the device and then use the appropriate resources or downloadthem from a web server. For example, in order to keep the size of your APK small, you can query thedevice's support for different GL texture formats when the application starts for the first time andthen download only the textures you need for that device.
For maximum performance and compatibility, your application should use ETC1 textures wherever itdoesn't impact the visual quality. However, because ETC1 cannot deal with images that have drasticchroma changes, such as line art and (most) text, and doesn't support alpha, it may not the bestformat for all textures.
With a single APK, you should try to use ETC1 textures and uncompressed textures wheneverreasonable, and consider the use of PVRTC, ATITC, or DXTC as a last resort when ETC1 does notsuffice.
Here's an example query for supported texture compression formats from inside aGLSurfaceView.Renderer
:
public void onSurfaceChanged(GL10 gl, int w, int h) { String extensions = gl.glGetString(GL10.GL_EXTENSIONS); Log.d("ExampleActivity", extensions); }
This returns a string that lists each of the supported compression formats.
Unless your APK file exceeds the Android Market size limit of 50MB, supporting multiple screensshould always be done with a single APK. Since Android 1.6, the Android system manages most of thework required for your application to run successfully on a variety of screen sizes anddensities.
To further optimize your application for different screen sizes and densities, you should providealternativeresources such as bitmap drawables at different resolutions and different layout designs fordifferent screen sizes.
For more information about how to support multiple screens with a single APK, read Supporting Multiple Screens.
Additionally, you should consider using a support library from the Compatibility Package so that you can add Fragments to your activity designswhen running on larger screens such as tablets.
If you want to support as many versions of the Android platform as possible, you should useonly APIs available in the lowest reasonable version. For example, your application may not requireAPIs newer than Android 2.1 (API Level 7), which makes an application available toover 95% of Android-powered devices (as indicated by the Platform Versions dashboard).
By using a support library from the Compatibility Package, you can also use APIsfrom some of the latest versions (such as Android 3.0) whilestill supporting versions as low as Android 1.6. The support library includes APIs for Fragments, Loaders, and more. Using the fragmentAPIs is particularly valuable so that you can optimize your user interface for large devices such astablets.
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. Byusing reflection, you can check whether the current device supports certain APIs. If the APIs arenot available, your application can gracefully disable and hide the feature.
Another way to use new APIs only when running on a version that supports them is to check theAPI level of the current device. That is, you can query the value of SDK_INT
and create different code paths depending on the API levelsupported by the device. For example:
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 }