我有一个项目,它有两种产品风格,有自己的目录:
的build.gradle:
android {
...
productFlavors {
free {
applicationId "com.sample.free"
buildConfigField "boolean", "free", "true"
}
paid {
applicationId "com.sample"
buildConfigField "boolean", "free", "false"
}
}
}
我有一个类(例如PaidOperationClass
),它仅用于paid
味道。所以,我把那个类放在src/paid/java
目录下。我有另一个类(例如CommonClass
),两种口味都使用它。所以我把它放在src/main/java
目录下:
src/main/ --> has CommonClass
src/free/
src/paid/ --> has PaidOperationClass
在CommonClass
我有一个方法,例如:
if(!BuildConfig.FREE) {
PaidOperationClass.doSomeStuff();
}
因此PaidOperationClass
被引用(具有导入)但从未被免费构建使用。
如果我构建paid
味道的应用程序,一切都很完美。但是,如果我尝试为free
味道构建它,它会失败,因为找不到引用但不必要的类。 如何在没有代码(类/方法)复制的情况下解决这个问题(例如将假PaidOperationClass
置于free
味道下)?是否有任何gradle选项忽略这种类型在构建时构建错误?
编辑:我需要一个不需要代码复制的gradle解决方案。基于注释的自定义脚本可能会在编译时删除不必要的产品风格代码。
答案 0 :(得分:2)
您无法执行此操作,因为import语句位于CommonClass
内,并且无法以免费方式解析PaidOperationClass
。
实现目标的一种方法是:
在 Free flavor :
中创建一个空类public class PaidOperationClass{
public static void doSomeStuff(){
//do nothing..
}
}
答案 1 :(得分:1)
最简单的解决方案可能是创建一个类:IPaidOperations,它位于PaidOperationClass实现的/ src / main目录中。然后只需使用CommonClass中的接口。
答案 2 :(得分:1)
您正在引用paid
包中的free
包,无论您是否使用:
if(!BuildConfig.FREE) {
PaidOperationClass.doSomeStuff();
}
所以我建议选择以下两种方法之一:
<强> 1 强>
因此,如果您有一段从未使用过的代码,为什么要将它保留在那里?将其取下并替换为:
if(!BuildConfig.FREE) {
// Do something within the imported packages.
}
否则,您必须导入paid
包。
<强> 2 强>
或者有两个free
包版本
free_paid
和free_no_paid
并删除paid
中对free_no_paid
的引用,并在不使用paid
进行编译时使用此项,并使用free_paid
使用paid
进行编译时的包。
答案 3 :(得分:1)
另一个解决方案是在CommonClass
和free
源集(但不在paid
中)创建两个main
es,其中包含特定于特定风格的代码。例如:
src/free/java/.../CommonClass.java
:
doSomeStuff() {
doSomeFreeStuff();
}
src/paid/java/.../CommonClass.java
:
doSomeStuff() {
doSomePaidStuff();
}
在这种情况下,main
源集中的代码可以引用CommonClass#doSomeStuff()
,无论构建哪种风味。只编译一个CommonClass
特定风味。换句话说,不是手动使用ifs,而是让gradle选择合适的类进行编译。
您还可以从free
中提取真正常见的代码(不依赖于paid
或CommonClass
特定的任何内容)到抽象类,即。 BaseCommonClass
放置在main
源集中,让CommonClass
扩展它。