Apk Splits



Introduction

The Split mechanism allows applications to be built for some forms of multi-apks more efficiently than using flavors.
The only types of supported multi-apks are
  • Density
  • ABIs
Using the new Split mechanism, building a hdpi, and an mdpi version of the same app will share a lot of the tasks (like javac, dx, proguard). Additionally, it will be considered a single variant and the same test app will be used to test every multi-apk.

When running the install or the connectedCheck tasks on a variant, Gradle will match the right APK output to each connected devices automatically.

If you want to also do another type of multi-APKs (defined here: http://developer.android.com/google/play/publishing/multiple-apks.html) you can also create Flavors (for instance for API level-based multi-apks), and each variants will have its own multi-outputs.

Density Splits

android {
  ...
  splits {
    density {
      enable true
      exclude "ldpi", "tvdpi", "xxxhdpi"
      compatibleScreens 'small', 'normal', 'large', 'xlarge'
    }
  }

enable: enables the density split mechanism
exclude: By default all densities are included, you can remove some densities.
include: indicate which densities to be included
reset(): reset the list of densities to be included to an empty string (this allows, in conjunctions with include, to indicate which one to use rather than which ones to ignore)
compatibleScreens: indicates a list of compatible screens. This will inject a matching <compatible-screens><screen ...> node in the manifest. This is optional.

Note that this will also always generate a universal APK with all the densities.

Sample: densitySplit

ABIs Splits

android {
  ...
  splits {
    abi {
      enable true
      reset()
      include 'x86', 'armeabi-v7a', 'mips'
      universalApk true
    }
  }
}

enable: enables the ABIs split mechanism
exclude: By default all ABIs are included, you can remove some ABIs.
include: indicate which ABIs to be included
reset(): reset the list of ABIs to be included to an empty string (this allows, in conjunctions with include, to indicate which one to use rather than which ones to ignore)
universalApk: indicates whether to package a universal version (with all ABIs) or not. Default is false.

Sample: ndkSanAngeles

Variant API & Version Code support.

Deprecation Warning: the current variant API contains some methods that have moved under its outputs. The method are still there, but will fail if there are 2+ outputs. They will be completely removed in 1.0
These are:
  • get/setOutputFile
  • getProcessResources
  • getProcessManifest
  • getPackageApplication/Library
  • getZipAlign
Additional methods on VariantOutput
  • String getAbiFilter()
  • String getDensityFilter()
  • Task getAssemble()
  • String getName()
  • String getBaseName()
  • String getDirName
  • set/getVersionOverride // optional versionCode override
  • int getVersionCode() // returns either the versionCode override from the output or the versionCode from the variant itself

Each generated APK must have a different versionCode. Similarly to looping on variants to set the versionCode, you can loop on a variant's outputs and set its versionCodeOverride.

// map for the version code
ext.versionCodes = ['armeabi-v7a':1, mips:2, x86:3]

import com.android.build.OutputFile

android.applicationVariants.all { variant ->
    // assign different version code for each output
    variant.outputs.each { output ->
        output.versionCodeOverride =
            project.ext.versionCodes.get(output.getFilter(OutputFile.ABI)) * 1000000 + android.defaultConfig.versionCode
    }
}

If you are using both flavors and splits for multi-apks, you should still use VariantOutput.setVersionCodeOverride(int) but you should compute the versionCode from both the split info (densityFilter and abiFilter) and the variant info.