Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Gradle 1.0 Computing Version code in multi-flavor setup

The code to compute version code for different product flavors is no longer working in the Android Gradle 1.0 system. I used the example code below before successfully.

http://tools.android.com/tech-docs/new-build-system/tips#TOC-Computing-Version-code-in-multi-flavor-setup.

productFlavors.get(0).versionCode is now computed as null.

Gradle code..

android {

  buildscript {
    repositories {
      mavenCentral()
    }
    dependencies {
      classpath 'com.android.tools.build:gradle:1.0.0'
    }
  }

  // This actual the app version code. Our given range is [0, 99999]
  defaultConfig.versionCode = 123

  // 2 dimensions of flavors. API is more important than ABI.
  flavorGroups "api", "abi"

  productFlavors {
    gingerbread {
      flavorGroup "api"
      minSdkVersion 10
      versionCode = 1
    }
    icecreamSandwich {
      flavorGroup "api"
      minSdkVersion 14
      // this must be higher than the gingerbread version to ensure update of the
      // app when the device gets a system update from GB to ICS
      versionCode = 2
    }
    x86 {
      flavorGroup "abi"
      ndk.abiFilter "x86"
      // this is the flavor part of the version code.
      // It must be higher than the arm one for devices supporting
      // both, as x86 is preferred.
      versionCode = 3
    }
    arm {
      flavorGroup "abi"
      ndk.abiFilter "armeabi-v7a"
      versionCode = 1
    }
    mips {
      flavorGroup "abi"
      // It must be higher than the arm one for devices supporting
      // both, as mips is preferred.
      ndk.abiFilter "mips"
      versionCode = 2
    }
    fat {
      flavorGroup "abi"
      // fat binary, lowest version code to be
      // the last option
      versionCode = 0
    }
  }

  // make per-variant version code
  applicationVariants.all { variant ->
    // get the version code of each flavor
    def apiVersion = variant.productFlavors.get(0).versionCode
    def abiVersion = variant.productFlavors.get(1).versionCode

    // set the composite code
     variant.mergedFlavor.versionCode = apiVersion * 1000000 + abiVersion * 100000 + defaultConfig.versionCode
  }
}
like image 522
TWilly Avatar asked Dec 16 '14 15:12

TWilly


People also ask

How do I get the current flavor in Gradle?

There is no "current flavor". The Gradle build file is building an object model of the build process. It is not an interpreted script only being used once a build is underway and a "current flavor" is known.

What is version code and version name?

The version code is an incremental integer value that represents the version of the application code. The version name is a string value that represents the “friendly” version name displayed to the users.

What is Gradle product flavors?

Product flavors are a powerful feature of the Gradle plugin from Android Studio to create customised versions of products. They form part of what we call Build Variants.

How do I add Flavours to my android?

Creating Product Flavor is pretty much easy in Android Studio, we simply need to add productFlavors block inside the Android block in the application-level build. gradle file. It's that simple to create product flavors.

What's new in Android Studio and Android Gradle?

Android Gradle plugin 3.5.0, along with Android Studio 3.5, is a major release and a result of Project Marble, which is a focus on improving three main areas of the Android developer tools: system health, feature polish, and fixing bugs. Notably, improving project build speed was a main focus for this update.

How to increase versioncode automatically in Gradle?

Actually, there are many ways to increase versionCode automatically, and here is one. First, create version.properties file and store your versionCode, versionBuild and versionName like this. Then, add a few lines of code to build.gradle file in app module. throw new GradleException ("Could not read version.properties!") That’s enough and it works!

What is the minimum version of Gradle that is compatible?

Compatibility Minimum version Default version Notes Gradle 6.7.1 N/A To learn more, see updating Gradle . SDK Build Tools 30.0.2 30.0.2 Install or configure SDK Build Tools. NDK N/A 21.4.7075529 Install or configure a different version ...

How to configure product flavors with the Android plugin?

When configuring product flavors with Android plugin 3.0.0 and higher, you must specify at least one flavor dimension, using the flavorDimensions property, and then assign each flavor to a dimension. Otherwise, you will get the following build error: Error:All flavors must now belong to a named flavor dimension.


1 Answers

From Google user guide

Multi-flavor variants

In some case, one may want to create several versions of the same apps based on more than one criteria. For instance, multi-apk support in Google Play supports 4 different filters. Creating different APKs split on each filter requires being able to use more than one dimension of Product Flavors.

Consider the example of a game that has a demo and a paid version and wants to use the ABI filter in the multi-apk support. With 3 ABIs and two versions of the application, 6 APKs needs to be generated (not counting the variants introduced by the different Build Types). However, the code of the paid version is the same for all three ABIs, so creating simply 6 flavors is not the way to go. Instead, there are two dimensions of flavors, and variants should automatically build all possible combinations.

This feature is implemented using Flavor Dimensions. Flavors are assigned to a specific dimension android { ...

flavorDimensions "abi", "version"

productFlavors {
    freeapp {
        flavorDimension "version"
        ...
    }

    x86 {
        flavorDimension "abi"
        ...
    }
} }

flavorGroups was replaced by flavorDimensions, so you need to use next code at build.gradle

   // 2 dimensions of flavors. API is more important than ABI.
flavorDimensions "api", "abi"

productFlavors {
    gingerbread {
        flavorDimension "api"
        minSdkVersion 10
        versionCode = 1
    }
    icecreamSandwich {
        flavorDimension "api"
        minSdkVersion 14
        // this must be higher than the gingerbread version to ensure update of the
        // app when the device gets a system update from GB to ICS
        versionCode = 2
    }
    x86 {
        flavorDimension "abi"
        ndk.abiFilter "x86"
        // this is the flavor part of the version code.
        // It must be higher than the arm one for devices supporting
        // both, as x86 is preferred.
        versionCode = 3
    }
    arm {
        flavorDimension "abi"
        ndk.abiFilter "armeabi-v7a"
        versionCode = 1
    }
    mips {
        flavorDimension "abi"
        // It must be higher than the arm one for devices supporting
        // both, as mips is preferred.
        ndk.abiFilter "mips"
        versionCode = 2
    }
    fat {
        flavorDimension "abi"
        // fat binary, lowest version code to be
        // the last option
        versionCode = 0
    }
}

// make per-variant version code
applicationVariants.all { variant ->
    // get the version code of each flavor
    def apiVersion = variant.productFlavors.get(0).versionCode
    def abiVersion = variant.productFlavors.get(1).versionCode

    // set the composite code
    variant.mergedFlavor.versionCode = apiVersion * 1000000 + abiVersion * 100000 + defaultConfig.versionCode
}

Update:

Add these lines to be able see versionCode at generated names of apk

    applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def apk = output.outputFile;
        def newName =  "${output.name}-${variant.mergedFlavor.versionCode}"
        if (variant.buildType.versionNameSuffix) {
            newName += "-${variant.buildType.versionNameSuffix}"
        }
        if (output.zipAlign) {
            output.zipAlign.outputFile = new File((File) apk.parentFile, newName + '-aligned.apk');
        }
        output.packageApplication.outputFile = new File((File) apk.parentFile, newName + ".apk")
    }
}

See bellow result of build:

    gingerbreadArmDebug-1100123.apk
    gingerbreadArmDebug-1100123-aligned.apk
    gingerbreadFatDebug-1000123.apk
    gingerbreadFatDebug-1000123-aligned.apk
    gingerbreadMipsDebug-1200123.apk
    gingerbreadMipsDebug-1200123-aligned.apk
    gingerbreadX86Debug-1300123.apk
    gingerbreadX86Debug-1300123-aligned.apk
    icecreamSandwichArmDebug-2100123.apk
    icecreamSandwichArmDebug-2100123-aligned.apk
    icecreamSandwichFatDebug-2000123.apk
    icecreamSandwichFatDebug-2000123-aligned.apk
    icecreamSandwichMipsDebug-2200123.apk
    icecreamSandwichMipsDebug-2200123-aligned.apk
    icecreamSandwichX86Debug-2300123.apk
    icecreamSandwichX86Debug-2300123-aligned.apk
    gingerbreadArmRelease-1100123.apk
    gingerbreadFatRelease-1000123.apk
    gingerbreadMipsRelease-1200123.apk
    gingerbreadX86Release-1300123.apk
    icecreamSandwichArmRelease-2100123.apk
    icecreamSandwichFatRelease-2000123.apk
    icecreamSandwichMipsRelease-2200123.apk
    icecreamSandwichX86Release-2300123.apk

Info from one of them, extracted by apktool:

version: 2.0.0-RC3
apkFileName: gingerbreadArmDebug-1100123.apk
isFrameworkApk: false
usesFramework:
  ids:
  - 1
sdkInfo:
  minSdkVersion: '10'
  targetSdkVersion: '21'
packageInfo:
  forced-package-id: '127'
versionInfo:
  versionCode: '1100123'
  versionName: '1.0'
compressionType: false

Update 2:

Published my test project at GitHub

like image 93
gio Avatar answered Oct 22 '22 00:10

gio