Gradle:为特定 flavor 添加库的依赖

46

我有一个图书馆项目和一个应用程序。我想为图书馆和应用程序都设置2个产品口味(storedev)。当我为应用程序构建store口味时,我希望从图书馆中使用store口味。同样,当我为应用程序构建dev口味时,我希望从图书馆中使用dev口味。我尝试为图书馆和应用程序设置相同的产品口味,但不起作用。

以下是我的配置:

Library

apply plugin: 'android-library'

android {
    compileSdkVersion 19
    buildToolsVersion "19.1.0"

    defaultConfig {
        applicationId "ro.amarkovits.graddletest.lib"
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors{
        store{

        }
        dev{

        }
    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

我有以下这些文件: src/main/res/values/strings.xml 和 src/store/res/values/strings.xml

应用程序

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion '19.1.0'
    defaultConfig {
        applicationId 'ro.amarkovits.mymodule.app'
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 1
        versionName '1.0'
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors{
        store{

        }
        dev{

        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':lib')
}
在这种情况下,我会遇到这个错误:Error:(12, 23) No resource found that matches the given name (at 'text' with value '@string/app_name')。app_name在库中的string.xml文件中被定义(在mainstore目录中都有)。
如果我从库中删除productFlavors,则可以构建但始终使用main目录中的values.xml

我编辑了我的问题并添加了更多细节。 - amarkovits
你找到解决方案了吗? - galex
@galex 不是,我已经停止搜索了。 - amarkovits
1
@amarkovits 找到了,看看我的回复! - galex
3个回答

60

在您的库中,您需要告诉Gradle每次构建每个变体:

android {
    publishNonDefault true
}

那么在您的应用程序中,最近我猜您可以这样做:

dependencies {
    (...)
    devCompile project(path: ':lib', configuration: 'devDebug') // or 'devRelease'
    storeCompile project(path: ':lib', configuration: 'storeRelease') // or 'storeDebug'
}

在官方文档的 Library Publication 中找到。

编辑:

自版本0.14.3(2014年11月18日)以来,您现在也可以拥有 Flavor-buildType-Compile 指令:

在 build.gradle 的 android{} 作用域之前添加以下内容:

configurations {
    devDebugCompile
    devReleaseCompile
    storeDebugCompile
    storeReleaseCompile
}

那么你可以根据 Flavor-BuildType 声明并使用不同版本的库:

dependencies {
    (...)
    devDebugCompile project(path: ':lib', configuration: 'devDebug')
    devReleaseCompile project(path: ':lib', configuration: 'devRelease')
    storeDebugCompile project(path: ':lib', configuration: 'storeDebug')
    storeReleaseCompile project(path: ':lib', configuration: 'storeRelease') 
}

编辑:

自从Android Gradle插件3.0.0以来,模块之间的依赖关系管理发生了变化。它会自动尝试匹配您的应用程序与它所依赖的库/模块之间的口味。

请参阅文档的详细解释


3
有什么办法可以做到 devDebug 使用 devDebug,devRelease 使用 devRelease(在这种情况下没有意义,但对我的用例有意义)? - Kevin DiTraglia
@KevinDiTraglia 我编辑了我的回答,因为你所要求的现在实际上已经存在。 - galex
我们需要再在模块设置中添加模块吗?还是以上代码已经足够了? - Meher
似乎无法在最新的AS上工作。如果我指定“configuration”,它无法获取项目。 - bj4947
@galex 不是的,AS 更改了它的工作方式。https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html - bj4947
显示剩余7条评论

5

为每个flavor定义特定的依赖关系可以使用"nameOfTheFlavorCompile"而不是"compile"

dependencies {
    storeCompile project(':lib')
}

2

我之前也遇到过类似的问题,就是编译器会忽略库项目中的产品风味。此外,即使你添加了更多的构建类型,它仍然会寻找和编译发布/调试源代码。

原因很简单:

  • 库插件不支持产品风味。
  • 似乎只支持调试和发布这两种构建类型。

编译器永远不会查找您将放在库项目存储目录中的任何内容。因此,您需要找到一个解决方法。

一种解决方法是在库中包含两种实现,并通过接口、多个构造函数等方式进行抽象化,然后让您的应用程序项目决定运行库的哪个部分。如果您使用proguard,则它会自动摆脱不需要的代码,如果它足够解耦(即使它没有解耦,也可能如此)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接