每个构建变体有两个 res 目录,Gradle 停止跟踪资源文件中的更改

Posted

技术标签:

【中文标题】每个构建变体有两个 res 目录,Gradle 停止跟踪资源文件中的更改【英文标题】:With two res directories per build variant, Gradle stopped tracking changes in resource files 【发布时间】:2014-01-25 07:21:20 【问题描述】:

我很天真地转而使用different app icons for each product flavour 沿着这些思路:

sourceSets.production 
    res.srcDirs = ['res', 'res-production']


sourceSets.beta 
    res.srcDirs = ['res', 'res-beta']


sourceSets.internal 
    res.srcDirs = ['res', 'res-internal']

事情是,在那之后,Gradle 不再注意到任何布局文件中的更改,例如 res/layout/activity_faq.xml,并且每次都需要一个干净的构建,如果我想要我的要包含在 APK 中的 XML 更改。

我最初以为这是 android Studio 问题,但实际上我可以在命令行上使用纯 Gradle 重现它,只需查看出现在 build/res/all/internal/debug/layout 下的文件。

当我运行./gradlew assembleInternalDebug 时,它会输出:

: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

这里,processInternalDebugResources 显示为UP-TO-DATE,而我认为它应该,当有更改的资源文件时。在每个口味的图标更改之前,在类似的 Gradle 输出中,processInternalDebugResources没有显示为最新的。

问题是,有什么方法可以解决这个问题,还是我偶然发现了 Android Gradle 插件中的错误?

我的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 插件 0.7.3.

编辑:出于其他原因,我从产品风格切换到 custom build types 以满足我的应用程序图标自定义需求。这个问题仍然存在,所以至少这不是特定于产品风味的。

【问题讨论】:

如果我在上述配置中注释掉sourceSets.internal(并将应用程序图标恢复到res 下的默认位置),Gradle 会再次开始注意到更改。所以确实问题与每种口味的资源目录有关。 我没仔细看,不过听起来值得报个bug。 @Scott:我环顾四周,这看起来是同一个问题:code.google.com/p/android/issues/detail?id=60154我在那里留下了评论。 【参考方案1】:

好的,解决了这个问题。原来是我build.gradle的一个小问题。

帮助我升级到 Gradle 插件 0.9.0 后,我开始收到如下错误:

* 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

好吧,我只是尝试从主要 sourceSets 中删除 res.srcDirs = ['res'],就是这样。

sourceSets 
    main 
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        // res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    
    // ...

我没有修改其余的 sourceSets 定义(res.srcDirs = ['res', 'res-beta'] 代表 sourceSets.beta 等等)。

一切都恢复正常:正在使用构建类型(或产品风格)特定的自定义图标,Gradle 再次正确地注意到增量构建中资源文件(例如布局)的更改!

(我通过使用我更改的build.gradle 测试 Gradle 插件版本 0.8.1、0.9.0 和 0.9.3 来验证问题确实出在我的配置中。确实,插件中的更改不是什么修复了这个问题,即使 0.9.0 是开始给我有用的错误消息的版本。)

这里的根本原因可能是使用“旧项目结构”和最初由 Eclipse 生成的 build.gradle。无论如何,在User Guide 中更仔细地研究源代码集和项目结构可能也会有所帮助。

【讨论】:

【参考方案2】:

我为同一个应用程序提供了多种构建风格,其中包含一些更改、图标和启动画面。每种风味都有自己的 res 文件夹。当我构建应用程序时,每个 apk 大小约为 50 mb :(。

所以我通过使用以下内容更新 build.gradle 文件解决了这个问题

`    sourceSets 
        main 
//            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
//            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        
        prod 
            manifest.srcFile 'prod/AndroidManifest.xml'
            resources.srcDirs = ['src/prod/res']
        
        dev 
            manifest.srcFile 'dev/AndroidManifest.xml'
            resources.srcDirs = ['src/dev/res']
        

`

在上面,我评论了resources.srcDirs = ['src'] 并添加了

           `prod 
                manifest.srcFile 'prod/AndroidManifest.xml'
                resources.srcDirs = ['src/prod/res']
            
            dev 
                manifest.srcFile 'dev/AndroidManifest.xml'
                resources.srcDirs = ['src/dev/res']
            `

【讨论】:

以上是关于每个构建变体有两个 res 目录,Gradle 停止跟踪资源文件中的更改的主要内容,如果未能解决你的问题,请参考以下文章

每个变体的 Android Gradle 自定义任务

Android Studio gradle 风味维度构建变体无法正常工作

Android Gradle - 仅针对特定任务过滤掉变体

Maven 或 Gradle 构建类型/变体

转载Gradle for Android 第四篇( 构建变体 )

选择 Android 库的构建变体的 Gradle 脚本