【发布时间】:2014-07-10 12:34:32
【问题描述】:
问题:
我想我的问题很常见。我有一个相当大的 gradle 代码库,我从中使用产品风格生成定制版本。这些产品风格通常需要来自src\main\java 的一个或多个类的定制版本。
我已阅读 Gradle 文档,并且在查看同一问题时也遇到了以下问题:
Using Build Flavors - Structuring source folders and build.gradle correctly
Build flavors for different version of same class
我理解为什么你不能在 src\main\java 和你的风格中定义相同的类,但是将类从 src\main\java 移动到你的产品风格中的解决方案有一个相当大的缺点。当您将一个类从 src\main\java 移动到您的最新版本以对其进行自定义时,您还需要将该类的原始未自定义版本的副本移动到所有其他以前的产品版本中,否则它们将不再构建。
您可能每次只需要从原始类中调整一两个不同的类(然后必须将这些类重新分配到风味目录),但随着时间的推移,移动的类的数量会增加,而剩下的数量会在每次您必须这样做时,src\main\java 都会减少。最终,大多数类都将具有风格(尽管大多数将是原件的副本),src\main\java 将几乎是空的,有点违背了整个 Gradle 构建结构的目的。
此外,您需要保留一个“默认”风格,每次开始新风格时都可以克隆它,这样您就知道您是从原始代码库中的所有类开始的。
我最初的解决方法:
使用 BuildConfig 中的字段来定义是否应该使用自定义类:
buildConfigField 'boolean', 'CUSTOM_ACTIVITY_X', 'true'
然后你可以使用如下代码:
final Intent intent = new Intent();
...
if (BuildConfig.CUSTOM_ACTIVITY_X) {
intent.setClass(ThisActivity.this, CustomActivityX.class);
} else {
intent.setClass(ThisActivity.this, DefaultActivityX.class);
}
startActivity(intent);
每个风格仍然需要一个副本 CustomActivityX,但它可以只是一个虚拟的空类,在你知道它不会被使用的地方。这意味着您的类的默认版本始终保留在 src\main\java 中。
改进的解决方法:
在尝试摆脱对所有其他风格的虚拟 CustomActivityX 的需求时,我已经研究过使用 Class.forName()。
例如:
final Class activityX;
if (BuildConfig.CUSTOM_ACTIVITY_X) {
try {
activityX = Class.forName("CustomActivityX");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else {
activityX = DefaultActivityX.class;
}
final Intent intent = new Intent();
...
intent.setClass(ThisActivity.this, activityX);
startActivity(intent);
然而,当您尝试使用它时,这显然会导致“activityX 可能尚未初始化”,因为try/catch 块。
如何克服?
【问题讨论】: