Android Studio:具有两个以上风味尺寸(风味组)的产品风味组合

时间:2016-05-04 08:18:06

标签: android android-studio android-gradle android-productflavors android-flavordimension

我正在使用Android Studio(v 2.1,gradle plugin v 2.1.0)开发Android应用程序。我的应用程序有各种版本,它们共享许多通用代码,所以我决定使用flavor大小和产品风格来定制代码和资源的时间和地点。只要我只有两个风味尺寸,这就行了罚款。例如,我的app.gradle

…
flavorDimensions "fruit", "color"

productFlavors {

    apple {
        dimension "fruit"
    }
    pear {
        dimension "fruit"
    }

    red {
        dimension "color"
    }
    yellow {
        dimension "color"
    }
}
…

和我的src文件夹

src/
    appleRed/
    appleYellow/
    pearRed/
    pearYellow/

每个人都有我的代码的自定义版本。再次,作为一个例子

src/
    appleRed/java/com/example/ExampleFragment.java
    appleYellow/java/com/example/ExampleFragment.java
    pearRed/java/com/example/ExampleFragment.java
    pearYellow/java/com/example/ExampleFragment.java

当然,ExampleFragment中没有src/main的实例。

在开发过程中的某个时刻,我必须包含免费付费版本的应用。我认为可以通过添加名为version的新风味维度和两个名为freepaid的产品风格来轻松实现:

 …
flavorDimensions "fruit", "color”, “version”

productFlavors {

    apple {
        dimension "fruit"
    }
    pear {
        dimension "fruit"
    }

    red {
        dimension "color"
    }
    yellow {
        dimension "color"
    }

    free {
        dimension "version"
    }
    paid {
        dimension “version”
    }
}
…

但是,Android Studio不再检测到由fruitcolor组合生成的自定义代码。因此,appleRedappleYellowpearRedpearYellow都不能用于自定义代码,而我能够重新获得配置的唯一方法就是使用所有组合所有三种风味维度:

  src/
      appleRedFree/java/com/example/ExampleFragment.java
      appleRedPaid/java/com/example/ExampleFragment.java
      appleYellowFree/java/com/example/ExampleFragment.java
      appleYellowPaid/java/com/example/ExampleFragment.java
      pearRedFree/java/com/example/ExampleFragment.java
      pearRedPaid/java/com/example/ExampleFragment.java
      pearYellowFree/java/com/example/ExampleFragment.java
      pearYellowPaid/java/com/example/ExampleFragment.java

这不好,因为ExampleFragment在同一个fruitColor*组合中重复appleRedFreeappleRedPaid具有相同的ExampleFragment)。资源(res文件夹中的资源)也会出现同样的问题。

我的问题是:

1)这是Android Studio中gradle的预期行为(,无法根据其维度组合产品风味的子集,当具有两种以上风味时尺寸)?

2)鉴于这是预期的行为,是否有另一种方法可以实现我的自定义而无需重复代码或没有单个文件内部带有 if-statement 例如if (BuildConfig.FLAVOR_version == "free") ...)?

请注意我说的是自定义代码可能很复杂,所以我不是要求基本的自定义,比如构建配置变量,变体过滤或类似的东西。

2 个答案:

答案 0 :(得分:11)

您想为某些风格使用相同的额外源目录;

  

appleRedFree + appleRedPaid - > SRC / appleRed
  pearRedFree + pearRedPaid - > SRC / pearRed
  appleYellowFree + appleYellowPaid - > SRC / appleYellow
  pearYellowFree + pearYellowPaid - > SRC / pearYellow

您可以为您的口味设置sourceSet

android {

    // Other stuff here

    flavorDimensions "fruit", "color”, “version”

    productFlavors {

        apple {
            dimension "fruit"
        }
        pear {
            dimension "fruit"
        }

        red {
            dimension "color"
        }
        yellow {
            dimension "color"
        }

        free {
            dimension "version"
        }
        paid {
            dimension “version”
        }
    }

    sourceSets {
        appleRedFree {
            java.srcDirs = ['src/main/java', 'src/appleRed/java']
        }

        appleRedPaid {
            java.srcDirs = ['src/main/java', 'src/appleRed/java']
        }

        appleYellowFree {
            java.srcDirs = ['src/main/java', 'src/appleYellow/java']
        }

        appleYellowPaid {
            java.srcDirs = ['src/main/java', 'src/appleYellow/java']
        }

        pearRedFree {
            java.srcDirs = ['src/main/java', 'src/pearRed/java']
        }

        pearRedPaid {
            java.srcDirs = ['src/main/java', 'src/pearRed/java']
        }

        pearYellowFree {
            java.srcDirs = ['src/main/java', 'src/pearYellow/java']
        }

        pearYellowPaid {
            java.srcDirs = ['src/main/java', 'src/pearYellow/java']
        }
    }

   // Other stuff here
}

答案 1 :(得分:2)

我有一些改进,因为我真的不喜欢复制/粘贴src集:)

因此您可以执行以下操作:

android {
    …
    applicationVariants.all { variant ->
        def flavors = variant.productFlavors
        def fruit = flavors[0].name
        def color = flavors[1].name
        def version = flavors[2].name

        def fruitColorSrcSet = fruit + color.capitalize()
        def srcSet = fruitColorSrcSet + version.capitalize()
        android.sourceSets."$srcSet".java.srcDirs += "src/$fruitColorSrcSet/java"
    }
}

我尚未对其进行测试,但是它基于我目前的实现方式,另外使用了variant.buildType.name


附录-设置资源目录使用

android.sourceSets."$srcSet".res.srcDirs = "src/$fruitColorSrcSet/res"