Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle Android Plugin - add custom flavor attribute?

Tags:

android

gradle

Is there any way to add custom attributes to productFlavor or buildType in android plugin for gradle? I'd like to have such additional flexibility in configuration of buildVariants, so that I can check my custom property when specifying tasks for buildVariants.

productFlavors {
    flavorGroups "drm", "storeType"
    googlePlay {
        flavorGroup "storeType"
        buildConfig "public static final String TARGET_STORE = \"google\";"
    }
    samsungApps {
        flavorGroup "storeType"
        buildConfig "public static final String TARGET_STORE = \"samsung\";"
    }

    platformDrm {
        flavorGroup "drm"
    }

    widevineAppDrm {
        flavorGroup "drm"
        minSdkVersion 9
        useWidevineAppDrmLib true
    }

}

so here you can see I've added custom attribute "useWidevineAppDrmLib" to build flavor. It would be nice to see the same attribute in buildVariant.mergedFlavor, so that I can check that attribute value and do build additional tasks, such as package additional .so files when the attribute is set to true:

android.applicationVariants.each { variant -> if(variant.mergedFlavor.useWidevineAppDrmLib ) { ... // add copy .so task } }

maybe there is a way to do that already but I didn't find out yet... checking build variant name for substring (flavor name) works for me, but it looks dirty.

Ideally I'd like to have a map of custom attributes of different types for buildType and productFlavor.

like image 477
blackdigger Avatar asked Jul 17 '13 10:07

blackdigger


2 Answers

You can extend an object to add a property dynamically. So you could do it on flavor object when they get added, using something like this:

// First declare a class that holds a boolean
class BooleanExtension {
  boolean value
  BooleanExtension(boolean value) {
    this.value = value
  }

  public void setValue(boolean value) {
    this.value = value
  }

  public boolean getValue() {
    return value
  }
}

android {
  // add the boolean extension to all flavor object when they are created.
  productFlavors.whenObjectAdded { flavor ->
    flavor.extensions.create("useWidevineAppDrmLib", BooleanExtension, false)
  }

  // then we can set the value on the extension of any flavor object
  productFlavors {
    widevineAppDrm {
      useWidevineAppDrmLib.value true
    }
  }
}

However this won't get passed to the merged flavor. So you'd have to do

android.applicationVariants.each { variant ->
  if (variant.productFlavors.get(0).useWidevineAppDrmLib.value) {
    ...
  }
}

Edited to make the code actually work from @blackdigger's feedback.

like image 118
Xavier Ducrohet Avatar answered Oct 20 '22 09:10

Xavier Ducrohet


There's an alternative solution which doesn't require the creation of your own custom class. You can utilize the already existing extras property which is already attached to the 'productFlavors' class. This was specifically designed to allow custom user defined variables.

android {
  // We can add any custom variable so long as it's prefaced with ext
  productFlavors {
    widevineAppDrm {
      ext.useWidevineAppDrmLib = true
    }
  }
}

Then you can later reference like so. Note, if you didn't add the custom variable to other productFlavors you'll need to be sure to check for it first, else gradle will complain about not finding the property.

android.applicationVariants.each { variant ->
    if (variant.productFlavors[0].ext.has("useWidevineAppDrmLib")) {
        if (variant.productFlavors.get(0).ext.useWidevineAppDrmLib) {
            ...
        }
    }
}
like image 33
Jay Soyer Avatar answered Oct 20 '22 09:10

Jay Soyer