不同android风格的通用代码

ken*_*nny 49 android gradle android-gradle-plugin

我正在构建4种不同风格的Android应用程序.

我有一个类Customization.java,其中3个相同,1个不同.

由于我不能在主文件夹和flavor文件夹中放置相同的类,因此我现在必须为这3种风格维护3个完全相同类的副本.

有没有办法只保留这个类的两个版本?

到目前为止我考虑过的事情:

  1. 我看了味道尺寸,但事实证明它们不适用于这种情况.
  2. 只保留一个文件中的一个文件并通过我的构建脚本复制它.

我想知道是否有更清洁的东西开箱即用.

Rav*_*yal 117

我想将CommonsWare的评论转换成答案.然后我将解释最终目录设置应该如何.我希望通过搜索帮助人们绊倒这个问题.

好吧,你可以覆盖各种口味的资源.因此,有一个共同的main/res/layout/和特定的味道 yourFlavorHere/res/layout/.

因此,如果Customization调用了活动的布局文件activity_customization.xml,您将使其共享副本在src/main/res/layout目录下的三种风格之间共享,并将修改后的布局xml flavorFour放在其相应的源集目录下使用src/flavorFour/res/layout.

它的工作方式是,由于第一至第三种味道(不同于第四种味道)没有提供它们自己的版本activity_customization.xml,它们将继承来自main源集的那种.

这是活动Java类变得棘手.另一种可能性是使用相同的活动实现来配置带有两个源目录的flavor:一个特定于flavor的目录和一个具有公共类实现的公共目录.

与资源不同,Java代码文件不会被合并或覆盖.因此,您不能main在任何一个flavor源集中使用具有相同完全限定类名的Java文件.如果这样做,您将收到重复的类错误.

要解决此问题,最简单的解决方案是将Customization活动移出main和移入每个flavor源集.这是有效的,因为flavor目录是相互排斥的(相互之间,而不是相互排斥main),从而避免了冲突.

但这意味着四种口味中的三种都有活动的副本 - 维护噩梦 - 只是因为其中一种口味需要对它进行一些改变.要解决此问题,我们可以引入另一个源目录,该目录仅保留三种风格之间共享的公共代码文件.

所以,build.gradle脚本看起来像

android {
    ...
    productFlavors {
        flavorOne {
            ...
        }
        flavorTwo {
            ...
        }
        flavorThree {
            ...
        }
        flavorFour {
            ...
        }
    }
    sourceSets {
        flavorOne.java.srcDir 'src/common/java'
        flavorTwo.java.srcDir 'src/common/java'
        flavorThree.java.srcDir 'src/common/java'
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意使用java.srcDir(而不是srcDirs)另一个Java源目录添加到现有的默认值src/flavorX/java.

现在我们需要做的就是删除公共Customization活动文件,src/common/java使其可用于一到三种口味.所需的修改版本flavorFour将在其自己的源设置下进行src/flavorFour/java.

因此,最终的项目结构看起来像

+ App // module
|- src
   |- common // shared srcDir
      |- java
       |- path/to/pkg
         |- CustomizationActivity.java // inherited by flavors 1, 2, 3
   + flavorOne
   + flavorTwo
   + flavorThree
   + flavorFour
      |- java
       |- path/to/pkg
         |- CustomizationActivity.java // per-flavor activity class
      |- res
         |- layout
            |- activity_customization.xml // overrides src/main/res/layout
   |- main
      + java
      |- res
         |- layout
            |- activity_customization.xml // inherited by flavors 1, 2, 3
Run Code Online (Sandbox Code Playgroud)


mat*_*dev 5

Ravi K Thapliyal 的解决方案对我的 gradle 3.5.3 不起作用

这是一个可行的替代解决方案:

将所有风格通用的代码移动到一个文件夹中,例如:

src/common/java
Run Code Online (Sandbox Code Playgroud)

然后将通用风味代码复制到通用 src 目录中:

src/generic/java
Run Code Online (Sandbox Code Playgroud)

这就是您应该将类​​的通用版本Customization.java复制到的位置。然后,将您的风味特定代码的副本创建到特定的 src 目录中,例如

src/specific/java
Run Code Online (Sandbox Code Playgroud)

然后您的build.gradle脚本应更新如下:

android {
    ...
    productFlavors {
        flavor1 {
            ...
        }
        flavor2 {
            ...
        }
        flavor3 {
            ...
        }
        flavor4 {
            ...
        }
    }
    sourceSets {
        flavor1.java.srcDirs('src/generic/java', 'src/common/java')
        flavor2.java.srcDirs('src/generic/java', 'src/common/java')
        flavor3.java.srcDirs('src/generic/java', 'src/common/java')
        flavor4.java.srcDirs('src/specific/java', 'src/common/java')
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:您的Customization.java班级应该从src/common/java

该解决方案也适用于活动类别