How to inject Android configuration to each subproject with Gradle?
Asked Answered
G

1

17

Rather than duplicating the android configuration block in each of the sub projects:

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 14
    }
}

I would much rather put this in the top-level/root gradle build file like:

subprojects{
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"

        defaultConfig {
            minSdkVersion 9
            targetSdkVersion 14
        }
    }
}

However, this doesn't work. :(

Error: "..Could not find method android() for arguments..."

Gametophyte answered 9/1, 2014 at 22:9 Comment(0)
G
28

The solution to this turned out to be:

subprojects{
    afterEvaluate {
        android {
            compileSdkVersion 19
            buildToolsVersion "19.0.0"

            defaultConfig {
                minSdkVersion 9
                targetSdkVersion 14
            }
        }
    }
}

As far as I know, this is because to process/use the android{...} at evaluation time means it must be present (ie. explicitly written or included as part of an 'apply plugin') as soon as it hits the subprojects in the root build file. And, more accurately, it means that the top-level project must have it defined (which it likely doesn't because it might not be an 'android' or 'android-library' build itself). However, if we push it off to after the evaluation then it can use what is available within each subproject directly.

This question + solution also assume that all subprojects are some form of android project (in my case true, but not necessarily for others). The safer answer would be to use:

subprojects{
    afterEvaluate {
        if(it.hasProperty('android')){
            android {
                compileSdkVersion 19
                buildToolsVersion "19.0.0"

                defaultConfig {
                    minSdkVersion 9
                    targetSdkVersion 14
                }
            }
        }
    }
}
Gametophyte answered 9/1, 2014 at 22:9 Comment(3)
This works otherwise nicely, but this way no subproject can override the default value. You should check for compileSdkVersion and buildToolsVersion existence before setting the values.Seasick
True, but on the flip side, if someone accidentally tries to override things in a subproject they won't get away with it ;)Gametophyte
For some reasons Android Gradle Plugin 3.5.2 did not accept this but complained that the submodules do not contain a compileSdkVersion (and everything else I tried to define commonly)Lanlana

© 2022 - 2024 — McMap. All rights reserved.