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

dum*_*ers 61 android android-gradle-plugin

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

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
Run Code Online (Sandbox Code Playgroud)

flavorA将完全使用源和资源,main同时flavorA2classA和中进行一些小的更改,并且classB包名称也更改为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"
        }
    }
...
Run Code Online (Sandbox Code Playgroud)

我通过选择构建变量来运行代码flavorA2.但是运行结果显示,gradle仍然选择类(classAclassB),main而不是使用内部更改的版本flavorA2.

我在这里错过了什么吗?

Has*_*eem 102

由于您拥有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
Run Code Online (Sandbox Code Playgroud)

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

  • @HassanIbraheem 很棒的帖子!您知道是否有一种方法可以将相同的 java 类用于两种风格而不需要复制它们?我的用例:我有 3 种风格,但其中两种应该使用相同的 java 类,只有其中一种不同。 (2认同)
  • @HassanIbraheem这对我来说是个问题,因为它使维护源代码变得更加困难.每次进行编辑时我都必须切换风味,并在编辑时复制粘贴相同的代码.除了匕首之外没有更好的选择吗?例如,我认为像@Target(flavor ='flavorA')这样的注释方法覆盖具有相同名称的方法是更好的解决方案.知道任何现有的库吗? (2认同)

Sco*_*rta 11

在主要构建变体中,A类是com.abc.flavorA.classA,并且在flavorA2其中com.abc.flavorA.mk2.classA.这是两个不同的完全限定类名,因此有两个不同的类.

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

有关语法的更多信息,请参阅Android Studio Update 0.4.0找不到buildConfig(),但简而言之,它看起来像这样:

productFlavors {
    flavor {
      buildConfigField "boolean", "MY_FLAG", "true"
    }
}
Run Code Online (Sandbox Code Playgroud)


ash*_*duh 5

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

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

        flavorA2 {
            java {
                srcDirs = ['src/flavorA2/java']
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)