在Android Studio中如何让两种构build风格从根风格inheritance?

我曾经有以下项目口味:

  1. 苹果
  2. 橙子

原本唯一的区别是applicationId/packageName 。 现在有一个不同的java文件。 一个自定义ArrayAdapter是确切的。 解决scheme是创buildsrc/Applesrc/Orange并且都从src/maininheritance。 我从src/main删除了java文件,并将一个副本放到了src/Applesrc/Orange并对其进行了适当的修改。 世界上一切都很好。

快进了几个星期,现在有大约10个不同的苹果和橙色的Java文件。 再次…没什么大不了的。 易于处理。 在src/Applesrc/Orange分开的java文件。

快进到今天。 我需要修改一些东西,因为我想有一个免费和高级版本。 免费版和高级版仅有不同的URL。 我打算简单地创build一个叫做:

  1. AppleFree
  2. ApplePremium
  3. OrangeFree
  4. OrangePremium

我有一个困境,但。 由于现在src/Applesrc/Orange有10个不同的文件已被更改…如果我更改AppleFree任何Java文件,我必须确保我在ApplePremium执行相同的ApplePremium 。 我正处在一个十字路口,希望我的问题在这一点上是有道理的。 我已经提出了三种可能的解决scheme,但是我不确定我将如何实现它们/什么是正确的方法/解决scheme不是我想要的。

解决scheme1:

使用if语句if (BuildConfig.FLAVOR==appleFree) {//use free Url} else {// use premium url}

问题:这两个url在技术上编译到apk中。 我不想要这个。

解决scheme2:

src / AppleFree和src / ApplePremium以某种方式从src / Apple父目录inheritance。

问题:不知道我将如何做到这一点。

解决scheme3:

像这样在build.gradle中添加免费和高级url?

  productFlavors { appleFree { applicationId "com.example.apple.free" versionName "1.0" url "http://freeurl.com" versionCode 1 } applePremium { applicationId "com.example.apple.premium" versionName "1.0" url "http://premiumurl.com" versionCode 1 } orangeFree { applicationId "com.example.orange.free" versionName "1.0" versionCode 1 url "http://freeurl.com" } orangePremium { applicationId "com.example.orange.premium" url "http://premiumurl.com" versionName "1.0" versionCode 1 } } 

问题:不知道如何使这项工作。

任何提示都很有帮助。

编辑:

最终解决scheme

 flavorGroups 'fruit', 'paid' productFlavors { apple { flavorGroup 'fruit' } orange { flavorGroup 'fruit' } free { flavorGroup 'paid' } premium { flavorGroup 'paid' } appleFree { applicationId "com.example.apple.free" versionName "1.0" buildConfigField 'String', 'BASE_URL', 'http://freeurl.com' versionCode 1 } applePremium { applicationId "com.example.apple.premium" versionName "1.0" buildConfigField 'String', 'BASE_URL', 'http://premiumurl.com' versionCode 1 } orangeFree { applicationId "com.example.orange.free" versionName "1.0" versionCode 1 buildConfigField 'String', 'BASE_URL', 'http://freeurl.com' } orangePremium { applicationId "com.example.orange.premium" buildConfigField 'String', 'BASE_URL', 'http://premiumurl.com' versionName "1.0" versionCode 1 } } 

Solutions Collecting From Web of "在Android Studio中如何让两种构build风格从根风格inheritance?"

你的问题有很多可能的解决scheme。 最原生的Gradle解决scheme将使用Flavor Dimensions,如http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Multi-flavor-variants

这也与您在解决scheme2时所考虑的内容类似。

它会这样工作:

 flavorDimensions 'fruit', 'paid' productFlavors { apple { dimension 'fruit' } orange { dimension 'fruit' } free { dimension 'paid' } premium { dimension 'paid' } } 

这将为您提供构build变体(和源文件夹)的地方,它将每个flavor维度中的所有可能性组合在一起,保持与flavorDimensions语句中指定组的顺序相同(即,它是appleFree ,而不是appleFree ),因此:

 * appleFree * applePremium * orangeFree * orangePremium 

在你的src /文件夹中,你可以有这些可能性:

 * src/main * src/apple * src/orange * src/free * src/premium * src/appleFree * src/applePremium * src/orangeFree * src/orangePremium 

解决scheme3

您可以使用buildConfigFieldbuildConfigField地指定进入BuildConfig类的常量:

 productFlavors { appleFree { buildConfigField 'String', 'MY_URL', 'value1' } applePremium { buildConfigField 'String', 'MY_URL', 'value2' } orangeFree { buildConfigField 'String', 'MY_URL', 'value3' } orangePremium { buildConfigField 'String', 'MY_URL', 'value4' } 

解决scheme1

我正在尝试解决scheme1的一些问题,但对于您的具体使用情况来说,这并不适用。 如果你在Java中有一个if条件来testing一个被声明为static final的布尔值,那么编译器可以静态地判断代码是否可达,如果不是,那么它将会剥离它。 从而:

 static final boolean DEBUG = false; ... if (DEBUG) { // do something } 

// do something的代码// do something根本就不会被编译。 这是Java编译器的一个有意和logging的行为,并允许您编写昂贵的debugging代码,这些代码不会被编译到您的发行版二进制文件中。 由于确切的原因, BuildConfig.DEBUG被声明为static final

有一个BuildConfig.FLAVOR ,但它被定义为String ,并没有得到同样的好处:

 static final String FLAVOR = "orange"; ... if (FLAVOR.equals("apple")) { // do something } 

编译器不够聪明做静态分析,看到/ / // do something无法访问,不编译它。 请注意,它在运行时可以正常工作 ,但死代码将包含在二进制文件中。

但是,如果它适合您,则可以从上面窃取buildConfigField方法,并在一些可能允许代码进行条件编译的变体中定义一个额外的布尔variables。这比直接在解决scheme3中定义string更复杂,但是如果你发现自己想要区分行为,而不经过特定风味的子类的麻烦,你可以走这条路。