With two res directories per build variant, Gradle stopped tracking changes in resource files
android, android-gradle-plugin, gradle
Solution
Ok, got this fixed. It turned out to be a small problem in my `build.gradle`.
What helped me was trying to upgrade to Gradle plugin 0.9.0, after which I started getting errors like these:
* What went wrong:
A problem occurred configuring root project 'MyProject'.
> SourceSets 'debug' and 'main' use the same file/folder for 'res': /path/to/MyProject/res
Well, I simply tried removing `res.srcDirs = ['res']` from main sourceSets, and that was it.
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
// res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// ...
}
I left the rest of the sourceSets definitions untouched (`res.srcDirs = ['res', 'res-beta']` for `sourceSets.beta` and so on).
Everything works again: the build type (or product flavour) specific custom icons are in use, and Gradle once again correctly notices changes to resource files (e.g. layouts) in incremental builds!
(I verified that the problem indeed was in my config by testing with Gradle plugin versions 0.8.1, 0.9.0 and 0.9.3 with my changed `build.gradle`. Indeed, changes in the plugin were not what fixed this, even if 0.9.0 was the version that started giving me the useful error message.)
Possibly the root cause here was using "old project structure" and `build.gradle` that was originally generated by Eclipse. In any case, studying source sets and project structure more carefully in the User Guide might have helped too.
Problem
I, quite innocently, switched to using different app icons for each product flavour along these lines: ``` sourceSets.production { res.srcDirs = ['res', 'res-production'] } sourceSets.beta { res.srcDirs = ['res', 'res-beta'] } sourceSets.internal { res.srcDirs = ['res', 'res-internal'] } ``` Thing is, after that, Gradle stopped noticing changes in any layout files, such as `res/layout/activity_faq.xml`, and requires a clean build each time, if I want my XML changes to be included in the APK. I first thought this was an Android Studio problem, but in fact I can reproduce it with pure Gradle, on the command line, simply looking at the files that appear under `build/res/all/internal/debug/layout`. When I run `./gradlew assembleInternalDebug`, it outputs: ``` :compileInternalDebugNdk UP-TO-DATE :preBuild UP-TO-DATE :preInternalDebugBuild UP-TO-DATE :prepareInternalDebugDependencies :compileInternalDebugAidl UP-TO-DATE :compileInternalDebugRenderscript UP-TO-DATE :generateInternalDebugBuildConfig UP-TO-DATE :mergeInternalDebugAssets UP-TO-DATE :mergeInternalDebugResources :processInternalDebugManifest UP-TO-DATE :processInternalDebugResources UP-TO-DATE :generateInternalDebugSources UP-TO-DATE :compileInternalDebugJava UP-TO-DATE :preDexInternalDebug UP-TO-DATE :dexInternalDebug UP-TO-DATE :processInternalDebugJavaRes UP-TO-DATE :validateDebugSigning :packageInternalDebug UP-TO-DATE :assembleInternalDebug UP-TO-DATE BUILD SUCCESSFUL ``` Here, `processInternalDebugResources` is shown to be `UP-TO-DATE`, while I think it should not be, when there are changed resource files. Before the icon-per-flavour change, in similar Gradle output, `processInternalDebugResources` was not shown up-to-date. Question is, any way to fix this, or did I stumble upon a bug in Android Gradle plugin? My `build.gradle`: ``` buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.7.3' } } apply plugin: 'android' repositories { mavenCentral() } dependencies { compile 'com.google.code.gson:gson:2.2.4' compile 'com.google.guava:guava:15.0' compile 'com.netflix.rxjava:rxjava-core:0.14.2' compile 'com.netflix.rxjava:rxjava-android:0.14.2' compile 'com.squareup.okhttp:okhttp:1.2.1' compile 'com.android.support:support-v4:13.0.0' compile 'com.android.support:support-v13:13.0.0' } android { compileSdkVersion 19 buildToolsVersion "19" defaultConfig { minSdkVersion 14 targetSdkVersion 19 } productFlavors { production { packageName "fi.company.app" } beta { packageName "fi.company.app.beta" } internal { packageName "fi.company.app.internal" } } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } // Move the tests to tests/java, tests/res, etc... instrumentTest.setRoot('tests') debug.setRoot('build-types/debug') release.setRoot('build-types/release') } // Custom res directories for different flavors; used for // setting different app icon. sourceSets.production { res.srcDirs = ['res', 'res-production'] } sourceSets.beta { res.srcDirs = ['res', 'res-beta'] } sourceSets.internal { res.srcDirs = ['res', 'res-internal'] } signingConfigs { release { // ... } } buildTypes { release { signingConfig signingConfigs.release // ... } } } ``` Gradle 1.9; Android Gradle plugin 0.7.3. Edit: For other reasons, I switched from product flavours to custom build types for my app icon customisation needs. This problem still remains, so at least this isn't product flavour specific.