Android buildTypes 与 productFlavors 错误

Android buildTypes vs. productFlavors error

决定从 Android gradle 插件 3.5.x 切换到 gradle 插件 4.10 和 Gradle 6.5 并卡住错误。

这是我的 build.gradle

defaultConfig {

    applicationId "com.example.myapp
    targetSdkVersion targetSdkVersionVar
    multiDexEnabled true
}

flavorDimensions "version"

productFlavors {
    kitkat {
        sourceSets { "src/android/kitkat" }
        dimension "version"
        minSdkVersion minSdkKitkat
        targetSdkVersion targetSdkKitkat
        versionNameSuffix "-kitkat"
    }
    nougat {
        sourceSets { "src/android/nougat" }
        dimension "version"
        minSdkVersion minSdkNougat
        targetSdkVersion targetSdkVersionVar
        versionNameSuffix "-nougat"
    }
}


buildTypes {

    debug {
        multiDexKeepFile file('multidex-config.txt')
        multiDexKeepProguard file('multidex-config.pro')
        minifyEnabled false
        zipAlignEnabled true
        sourceSets {

            //main.java.srcDirs += 'src/main/kotlin'
            main {
                java.srcDirs = ['src/android/default/java/', 'src/common/java/']
                jni.srcDirs = [] //disable ndk support
                manifest.srcFile 'src/android/default/AndroidManifest.xml'
                resources.srcDirs = ['src/android/default']
                aidl.srcDirs = ['src/android/default']
                renderscript.srcDirs = ['src/android/default']
                res.srcDirs = ['src/android/default/res']
                assets.srcDirs = ['src/android/default/assets']
            }
            test {
                java.srcDirs = ['src/test/java']
            }
            androidTest {
                java.srcDirs = ['src/androidTest/java']
            }
        }
    }
    release {
        multiDexKeepFile file('multidex-config.txt')
        multiDexKeepProguard file('multidex-config.pro')
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        zipAlignEnabled true
        sourceSets {

            main {
                java.srcDirs = ['src/android/default/java/', 'src/common/java/']
                jni.srcDirs = [] //disable ndk support
                manifest.srcFile 'src/android/default/AndroidManifest.xml'
                resources.srcDirs = ['src/android/default']
                aidl.srcDirs = ['src/android/default']
                renderscript.srcDirs = ['src/android/default']
                res.srcDirs = ['src/android/default/res']
                assets.srcDirs = ['src/android/default/assets']
            }
            test {
                java.srcDirs = ['src/test/java']
            }
            androidTest {
                java.srcDirs = ['src/androidTest/java']
            }
        }
    }
}

尝试构建时我收到以下错误消息:

Could not determine the dependencies of task ':app:checkKitkatReleaseLibraries'.
> Could not resolve all task dependencies for configuration ':app:kitkatReleaseReverseMetadataValues'.
   > Could not resolve project :app.
     Required by:
         project :app
      > The consumer was configured to find a usage of 'android-reverse-meta-data' of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'version' with value 'kitkat'. However we cannot choose between the following variants of project :app:
          - kitkatDebugAndroidTestCompile
          - kitkatDebugAndroidTestRuntime
          - kitkatDebugRuntime
          - kitkatDebugUnitTestCompile
          - kitkatDebugUnitTestRuntime
          - kitkatReleaseRuntime
          - kitkatReleaseUnitTestCompile
          - kitkatReleaseUnitTestRuntime
          - nougatDebugAndroidTestCompile
          - nougatDebugAndroidTestRuntime
          - nougatDebugRuntime
          - nougatDebugUnitTestCompile
          - nougatDebugUnitTestRuntime
          - nougatReleaseRuntime
          - nougatReleaseUnitTestCompile
          - nougatReleaseUnitTestRuntime
        All of them match the consumer attributes:
          - Variant 'kitkatDebugAndroidTestCompile' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatDebugAndroidTestRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatDebugRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatDebugUnitTestCompile' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatDebugUnitTestRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatReleaseRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatReleaseUnitTestCompile' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'kitkatReleaseUnitTestRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatDebugAndroidTestCompile' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatDebugAndroidTestRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatDebugRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatDebugUnitTestCompile' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatDebugUnitTestRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatReleaseRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatReleaseUnitTestCompile' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
          - Variant 'nougatReleaseUnitTestRuntime' capability myapp:app:unspecified:
              - Unmatched attributes:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'release')
                  - Doesn't say anything about its usage (required a usage of 'android-reverse-meta-data')
                  - Provides attribute 'org.jetbrains.kotlin.localToProject' with value 'local to :app' but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Doesn't say anything about version (required 'kitkat')
        The following variants were also considered but didn't match the requested attributes:
          - Variant 'kitkatDebugApiElements' capability myapp:app:unspecified declares a component, as well as attribute 'version' with value 'kitkat':
              - Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' and the consumer needed a usage of 'android-reverse-meta-data' of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release'
          - Variant 'kitkatDebugRuntimeElements' capability myapp:app:unspecified declares a component, as well as attribute 'version' with value 'kitkat':
              - Incompatible because this component declares a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' and the consumer needed a usage of 'android-reverse-meta-data' of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release'
          - Variant 'kitkatReleaseApiElements' capability myapp:app:unspecified declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'version' with value 'kitkat':
              - Incompatible because this component declares an API of a component and the consumer needed a usage of 'android-reverse-meta-data' of a component
          - Variant 'kitkatReleaseRuntimeElements' capability myapp:app:unspecified declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'version' with value 'kitkat':
              - Incompatible because this component declares a runtime of a component and the consumer needed a usage of 'android-reverse-meta-data' of a component
          - Variant 'nougatDebugApiElements' capability myapp:app:unspecified:
              - Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'version' with value 'nougat' and the consumer needed a usage of 'android-reverse-meta-data' of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'version' with value 'kitkat'
          - Variant 'nougatDebugRuntimeElements' capability myapp:app:unspecified:
              - Incompatible because this component declares a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'version' with value 'nougat' and the consumer needed a usage of 'android-reverse-meta-data' of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'version' with value 'kitkat'
          - Variant 'nougatReleaseApiElements' capability myapp:app:unspecified declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release':
              - Incompatible because this component declares an API of a component, as well as attribute 'version' with value 'nougat' and the consumer needed a usage of 'android-reverse-meta-data' of a component, as well as attribute 'version' with value 'kitkat'
          - Variant 'nougatReleaseRuntimeElements' capability myapp:app:unspecified declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release':
              - Incompatible because this component declares a runtime of a component, as well as attribute 'version' with value 'nougat' and the consumer needed a usage of 'android-reverse-meta-data' of a component, as well as attribute 'version' with value 'kitkat'

在那之前,当我使用 gradle-tools v 3.x - 它工作得非常好。

有什么想法、想法、提示、线索吗?

好吧,为了使用不同的后端,我不会指定比调试和发布更多的构建类型。相反,我会使用其中一些技术:

  • 更多口味,
  • 自定义构建配置字段(文档 here),
  • 组合多种产品口味(文档 here)。

您可以使用 BuildConfig class.

在应用程序代码中访问构建类型、构建风格和自定义字段

简单风格的方法

  • 构建类型:
    • debug
    • release
  • 口味:
    • dev
    • test
    • live

这会导致这些构建变体(您不必使用所有变体):

  • devDebug
  • devRelease
  • testDebug
  • testRelease
  • liveDebug
  • liveRelease

使用维度组合多种口味的方法

  • 风味维度:

    • backend
    • target
  • 构建类型:

    • debug
    • release
  • 口味:

  • target维度:

    • dev
    • test
    • live
  • backend维度:

    • production
    • test

这会导致这些构建变体(同样,您不必使用所有变体):

  • productionDevDebug
  • productionDevRelease
  • productionTestDebug
  • productionTestRelease
  • productionLiveDebug
  • productionLiveRelease
  • testDevDebug
  • testDevRelease
  • testTestDebug
  • testTestRelease
  • testLiveDebug
  • testLiveRelease

使用构建字段

在构建类型和构建风格声明中使用附加值,例如:

buildConfigField "boolean", "production_backend", "false"

buildConfigField "String", "backend", "\"production\""

关注这个Linkhttps://www.journaldev.com/21533/android-build-types-product-flavors

按照@Chriki 的评论尝试制定最小的可重现问题并突然找到了解决方案。魔术在声明中:

android {
    ...
    dynamicFeatures = [":app"]
}

每当我评论这一行时,一切正常。

P.S。这里应该是仇恨辐射到gradlelogs/debug的留言,居然没有那些logging/messaging。最后我花了将近一周的时间寻找解决方案,最后无意中找到了。

如果@Chriki 会 post 回答我会赏金给他。

您遇到的问题似乎是您的主项目使用了具有风味维度的库,而您的应用不知道要使用哪个库。您应该在 defaultConfig 块中使用 missingDimensionStrategy 来指定默认风格。例如:

missingDimensionStrategy 'dimension', 'flavor1', 'flavor2'

请查看 this link 了解更多详情。

我遇到了同样的问题,但我正在处理多个 gradle 文件项目,在为每个文件添加变体后它工作正常。

在以下情况下会发生此错误。您有这些模块和依赖项:

                  app (free/paid)
                   |
featureA       featureB          featureC
   |               |                |
       \                      /
             libraryX (free/paid)

app 模块有 2 种风格:freepaidfeature 模块中的 None 有这两种风格,但 libraryX 有!现在,当 feature 模块依赖于 libraryX 时,它们必须明确地告诉 gradle 他们想要 freeLibraryXDebug 还是 paidLibraryXDebug。但是 feature 模块不能说 freeImplementation(project(":libraryX"))paidImplementation(project(":libraryX")) 因为它们本身没有这些风格。

two ways可以解决这些:

  1. feature 模块总是选择一种特定的风格,使用 defaultConfig 中的 missingDimensionStrategy,如 here 所述。这种方法的问题是 feature 模块总是依赖于一种特定的风格(free/paid),无论选择什么 app 模块风格(来自左侧的 AndroidStudio“Build Variants”选项卡或来自终端命令)

  2. feature 模块还声明了 2 种风格(freepaid),然后使用 implementation(project(":libraryX"))。为 app 模块选择的风格将向下级联到 feature 模块和 libraryX 模块,一切都会自动进行。问题是样板文件,如果你有数十个 feature 模块,它们都需要在 gradle 文件中声明 2 种风格。为了消除双模板和代码重复,您可以将 productFlavors 声明提取到单独的 gradle 文件中,并将其作为 plugin 应用到每个 feature 模块中。 Example codes for gradle kotlin dsl and discussion here.

我无法通过查看 app 模块选择的风格来选择 libraryX's 风格,而不在中间向 feature 模块引入风格。