根据构建参数更改我的来源
Changing my sources according on the build parameters
TL;DR:根据传递给 gradle 的参数更改我的来源的干净方法是什么?
我正在构建一个 Android 应用程序,它依赖于库 A
。我希望能够支持 A
的多个版本(假设我想同时支持 v1
和 v2
)。我的意思是我希望能够构建 myapp-withAv1.apk
和 myapp-withAv2.apk
.
我发现在编译时很容易 select 我想要的 A
版本(例如,我可以在 build.gradle
的变量中引用这个版本文件,然后使用 ./gradlew -PversionOfA=v1 build
).
启动构建
但是另一个困难是 A
可以更改它的 public API 所以我需要根据我正在构建的版本更改我的代码。如果我使用 C++ 或 C# 会很容易(感谢 #ifdef
),但我一直无法找到一种方法来做到这一点而无需过多的代码重复,如果你能指出我,我会很高兴一种实现它的方法。
(请注意,尝试用 if(version == v1)
之类的东西来隔离代码分支是行不通的,因为它会导致代码分支调用 A
的方法,但该方法不可用,所以构建会失败)
我 运行 遇到过类似的问题,答案是 productFlavors
in android 或 sourceSets
for a generic jar。基本上你需要在每个源集中指定一个接口的实现。
# define the interface in the main
/src/main/java/com/me/IMyInterface.java
# create a v1 and v2 sourceset with the implementation, note paths are the same
/src/v1/java/com/me/MyImplementation.java
/src/v2/java/com/me/MyImplementation.java
现在在您的 gradle 中定义 productFlavors
android {
productFlavors {
v1 {
buildConfigField 'string', 'FLAVOR', 'v1'
}
v2 {
buildConfigField 'string', 'FLAVOR', 'v2'
}
}
//...
}
现在,当您引用实现时,您将获得定义为产品风味名称的版本的 sourceSet
。
// since the package is the same we are unaware of which we are calling
// now we can treat them as the same regardless of the underlying
// implementation differences between v1/v2
import com.me.MyImplementation;
public String doSomethingWithImplementation() {
MyImplementation impl = new MyImplementation();
// here if we are executing in the productFlavor v1
// apk we get the code from the v1 folder, same for v2 apk
return impl.doSomething()
}
我在 2002 年为 J2ME 开发时也有类似的需求,所以开发了 a preprocessor, today it has support for maven,gradle and ant, you can try it for android, a test android project which can be used as sample can be found in the project repository
对于预处理器,Java sources look like that
TL;DR:根据传递给 gradle 的参数更改我的来源的干净方法是什么?
我正在构建一个 Android 应用程序,它依赖于库 A
。我希望能够支持 A
的多个版本(假设我想同时支持 v1
和 v2
)。我的意思是我希望能够构建 myapp-withAv1.apk
和 myapp-withAv2.apk
.
我发现在编译时很容易 select 我想要的 A
版本(例如,我可以在 build.gradle
的变量中引用这个版本文件,然后使用 ./gradlew -PversionOfA=v1 build
).
但是另一个困难是 A
可以更改它的 public API 所以我需要根据我正在构建的版本更改我的代码。如果我使用 C++ 或 C# 会很容易(感谢 #ifdef
),但我一直无法找到一种方法来做到这一点而无需过多的代码重复,如果你能指出我,我会很高兴一种实现它的方法。
(请注意,尝试用 if(version == v1)
之类的东西来隔离代码分支是行不通的,因为它会导致代码分支调用 A
的方法,但该方法不可用,所以构建会失败)
我 运行 遇到过类似的问题,答案是 productFlavors
in android 或 sourceSets
for a generic jar。基本上你需要在每个源集中指定一个接口的实现。
# define the interface in the main
/src/main/java/com/me/IMyInterface.java
# create a v1 and v2 sourceset with the implementation, note paths are the same
/src/v1/java/com/me/MyImplementation.java
/src/v2/java/com/me/MyImplementation.java
现在在您的 gradle 中定义 productFlavors
android {
productFlavors {
v1 {
buildConfigField 'string', 'FLAVOR', 'v1'
}
v2 {
buildConfigField 'string', 'FLAVOR', 'v2'
}
}
//...
}
现在,当您引用实现时,您将获得定义为产品风味名称的版本的 sourceSet
。
// since the package is the same we are unaware of which we are calling
// now we can treat them as the same regardless of the underlying
// implementation differences between v1/v2
import com.me.MyImplementation;
public String doSomethingWithImplementation() {
MyImplementation impl = new MyImplementation();
// here if we are executing in the productFlavor v1
// apk we get the code from the v1 folder, same for v2 apk
return impl.doSomething()
}
我在 2002 年为 J2ME 开发时也有类似的需求,所以开发了 a preprocessor, today it has support for maven,gradle and ant, you can try it for android, a test android project which can be used as sample can be found in the project repository 对于预处理器,Java sources look like that