Advanced app deployment

In Chapter 4, Creating Build Variants, we looked at several ways to create multiple versions of the same app, using build types and product flavors. However, in some cases, it might be easier to use a more specific technique, such as APK splits.

Split APK

Build variants can be seen as separate entities, that can each have their own code, resources, and manifest file. APK splits, on the other hand, only impact the packaging of an app. The compilation, shrinking, obfuscation, and so on are still shared. This mechanism allows you to split APKs based on either density or application binary interface (ABI).

You can configure splits by defining a splits block inside the android configuration block. To configure density splits, create a density block inside the splits block. If you want to set up ABI splits, use an abi block.

If you enable density splits, Gradle creates a separate APK for each density. You can manually exclude certain densities if you do not need them, to speed up the build process. This example shows how to enable density splits and exclude devices with low density:

android {
    splits {
        density {
            enable true
            exclude 'ldpi', 'mdpi'
            compatibleScreens 'normal', 'large', 'xlarge'
        }
    }
}

If you only support a few densities, you can use include to create a whitelist of densities. To use include, you first need to use the reset() property, which resets the list of included densities to an empty string.

The compatibleScreens property in the preceding snippet is optional, and injects a matching node in the manifest file. The configuration in the example is for an app that supports normal to extra large screens, excluding devices with small screens.

Splitting APKs based on the ABI works in the same way, and all of the properties are the same as the properties for density splits, except for compatibleScreens. ABI splits have nothing to do with screen size, so there is no property called compatibleScreens.

The result of executing a build after configuring the density splits is that Gradle now creates one universal APK and several density-specific APKs. This means you will end up with a collection of APKs like this:

app-hdpi-release.apk
app-universal-release.apk
app-xhdpi-release.apk
app-xxhdpi-release.apk
app-xxxhdpi-release.apk

There is one caveat to using APK splits, though. If you want to push multiple APKs to Google Play, you will need to make sure every APK has a different version code. This means that each split should have a unique version code. Luckily, by now you are able to do this in Gradle by looking at the applicationVariants property.

The following snippet comes straight from the Android plugin for Gradle documentation, and shows how to generate different version codes for each APK:

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
    }
}

This little snippet checks which ABI is used on a build variant, and then applies a multiplier to the version code to make sure each variant has a unique version code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset