Reputation: 2837
I have this code at the end of my build.gradle file:
project.afterEvaluate {
// If you add/change build types, you have to add to/change
// these task names.
mergeDebugAssets.dependsOn project.tasks.getByName('downloadLicenses')
mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')
}
See: Copy generated third party licenses to assets for the full code
This used to work fine (regardless of which buildType was set) but if updating my dependencies to the latest version this triggers an exception (when building with buildType='debug'):
Could not get unknown property 'mergeReleaseAssets' for project ':application'
My thought was that maybe split this block in two and put them under the buildTypes configuration. This doesn't work though, as it tries to evaluate the code anyway and crashes.
Any ideas?
Update 1: Root cause? https://code.google.com/p/android/issues/detail?id=219732
Update 2: A horrible workaround:
try {
mergeDebugAssets.dependsOn project.tasks.getByName('downloadLicenses')
} catch (Exception e) {
// Expected when building variant Release
}
try {
mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')
} catch (Exception e) {
// Expected when building variant Debug
}
Upvotes: 3
Views: 8547
Reputation: 779
The reason that you get an error referencing a release task in afterEvaluate
is probably because Android Studio's Instant Run feature uses a special Android Gradle plugin feature to only build the debug application variant. This means that only the debug tasks are created, hence why the release tasks can't be found when you reference them.
There are several ways to deal with this:
Search for the dependent task by name using a string. If the Android build system changes the task name in the future, your additional build rules won't run, but you might not even notice.
To determine if release tasks exist, check for the existence of a task whose name is unlikely to change in the future. Maybe assembleRelease
fits this bill.
To determine if release tasks exist, check if the release application variant is built with something like:
project.afterEvaluate {
if (!android.applicationVariants.matching { it.buildType.name == 'release' }.isEmpty()) {
mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')
}
}
The last option looks kind of gross, but hopefully it will fail-fast if the Android build system task names change in the future.
Upvotes: 8
Reputation: 1048
The reason you get exception in case of debug buildType is because mergeReleaseAssets
task is not created. You can do the following instead:
project.tasks.findByName('mergeReleaseAssets')?.dependsOn project.tasks.getByName('downloadLicenses')
or even omit project
:
tasks.findByName('mergeReleaseAssets')?.dependsOn tasks.getByName('downloadLicenses')
This uses safe navigation operator on nullable return type, so it's clearer than try/catch workaround.
Upvotes: 5