为同一类的不同版本构建风味

时间:2014-05-16 15:16:27

标签: android android-gradle

我有一个项目,结构如下:

project/
   |
   |---src/
        |---flavorA2/
        |      |
        |      |---java/
        |      |     |---com.abc.flavorA.mk2
        |      |                 |-----classA.java
        |      |                 |-----classB.java
        |      |---res/
        |      |---AndroidManifest.xml
        |
        |---main
        |      |---java/
        |      |     |---com.abc.flavorA
        |      |                 |-----classA.java
        |      |                 |-----classB.java
        |      |                 |-----classC.java
        |      |                 |-----classD.java
        |      |---res/
        |      |    |---drawable/
        |      |    |---layout/
        |      |    |---values/
        |      |         
        |      |---AndroidManifest.xml
        |
        |---flavorA

flavorA将完全使用main中的来源和资源,而flavorA2classAclassB中有一些小的更改,并且包名称也会更改到com.abc.flavorA.mk2

我有build.gradle这样的文件:

...
buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    productFlavors {
        flavorA2 {
            packageName "com.abc.flavorA.mk2"
            versionCode 2
            versionName "1.0.1"
        }

        flavorA {
            packageName "com.abc.flavorA"
        }
    }
...

我通过选择flavorA2的构建变体来运行代码。但是,运行结果显示,草图仍然从classA中选择了类classBmain},而不是在flavorA2中使用更改后的版本。

我在这里错过了什么吗?

3 个答案:

答案 0 :(得分:96)

由于您拥有2个不同包下的类,因此这些类完全不同。所以这些课程并没有相互替代。

使用flavor,您无法覆盖类文件。因此,实现目标的一种方法是将这些类从main移出flavorA

所以你会有这样的事情:

project/
   |
   |---src/
        |---flavorA2/
        |      |
        |      |---java/
        |      |     |---com.abc
        |      |                 |-----classA.java
        |      |                 |-----classB.java
        |      |---res/
        |      |---AndroidManifest.xml
        |
        |---main/
        |      |---java/
        |      |     |---com.abc.flavorA
        |      |                 |-----classC.java
        |      |                 |-----classD.java
        |      |---res/
        |      |    |---drawable/
        |      |    |---layout/
        |      |    |---values/
        |      |         
        |      |---AndroidManifest.xml
        |
        |---flavorA/
        |      |---java/
        |      |     |---com.abc
        |      |                 |-----classA.java
        |      |                 |-----classB.java

这样,无论何时选择一种风味,都只能看到一个版本的ClassA和ClassB。

答案 1 :(得分:11)

在主要版本变体中,A类是com.abc.flavorA.classA,而flavorA2com.abc.flavorA.mk2.classA。这是两个不同的完全限定类名,因此有两个不同的类。

你无法真正覆盖整个类的风格。根据您想要做的事情,您可能希望查看BuildConfig机制 - 简而言之,这是一个由构建系统生成的类,它可以具有根据具体情况而变化的值或语句构建类型和风格。您可以使用运行时代码来查看该类中的常量并改变其行为。

有关语法的详细信息,请参阅Android Studio Update 0.4.0 could not find buildConfig(),但简而言之,它看起来像这样:

productFlavors {
    flavor {
      buildConfigField "boolean", "MY_FLAG", "true"
    }
}

答案 2 :(得分:2)

您需要在构建文件中指定sourceSets。您需要修改目录结构以使其只有文件夹名称不同,java目录下的所有内容都应该相同,因此从类名中删除mk2。我不确定语法是否完全正确,但它应该如下所示:

android {
    sourceSets {
        flavorA {
            java {
                srcDirs = ['src/flavorA/java']
            }
        }

        flavorA2 {
            java {
                srcDirs = ['src/flavorA2/java']
            }
        }
    }
}