我正在尝试使用Gradle配置包含一些外部库的项目。使用Gradle我可以使用Build Variants为主应用程序设置不同的环境配置(在配置文件中有一个类),这样我就可以根据这些变量执行代码。
问题是我如何为图书馆项目做同样的事情?我为这个项目创建了这个库,我想为不同的场景设置不同的Build Variants。
举个例子: 在库中,当在调试模式下运行时,然后打印所有日志,以便我可以在开发时看到它们。在发布模式下不要。
文件结构:
src ----- > debug -> java -> config -> PlayerEnvConfig
main -> com.mypackagename -> etc...
release -> java -> config -> PlayerEnvConfig
调试代码: 包配置;
/**
* Environment configuration for Release
*/
public final class PlayerEnvConfig {
public static final boolean USE_REPORTING = true;
public static final boolean USE_ANALYTICS = true;
public static final boolean USE_LOGGING = false;
public static final boolean USE_DEBUG_LOGGING = false;
public static final boolean USE_DEBUGING = false;
}
发布中的代码:
package config;
/**
* Environment configuration for Release
*/
public final class PlayerEnvConfig {
public static final boolean USE_REPORTING = true;
public static final boolean USE_ANALYTICS = true;
public static final boolean USE_LOGGING = false;
public static final boolean USE_DEBUG_LOGGING = false;
public static final boolean USE_DEBUGING = false;
}
问题是,对于主项目,我可以使用此Build类型为不同的场景配置不同的应用程序,但是如何为Library Project执行相同的操作?
因为从我在http://tools.android.com/tech-docs/new-build-system/user-guide中读到的那一刻起,库只会在测试时使用调试模式。
有什么想法吗?
谢谢!
答案 0 :(得分:14)
来自google code issue的@bifmadei答案对我有帮助:
尝试在依赖项目
中设置此项android {
publishNonDefault true
...
}
这在使用它的项目中
dependencies {
releaseCompile project(path: ':theotherproject', configuration: 'release')
debugCompile project(path: ':theotherproject', configuration: 'debug')
}
从这里采取:https://code.google.com/p/android/issues/detail?id=66805
答案 1 :(得分:12)
不确定您的配置有什么问题,但关于您的需求,我会采用不同的方式。
在gradle构建文件中,您可以使用buildConfig
关键字向BuildConfig.java
生成的类添加特定行。
所以你可以在build.gradle
:
release {
buildConfig "public static final String USE_REPORTING = true;"
}
debug {
buildConfig "public static final String USE_REPORTING = false;"
}
所以只有一个PlayerEnvConfig
public static final boolean USE_REPORTING = BuildConfig.USE_REPORTING;
甚至不再PlayerEnvConfig
并直接使用BuildConfig
类。
编辑自更新以来,语法已更改:
buildConfigField "<type>", "<name>", "<value>"
答案 2 :(得分:4)
https://code.google.com/p/android/issues/detail?id=52962中记录了这一点。正如您所知,构建类型不会传播到库项目,并且没有一个好的解决方法。如果您可以控制库项目的代码,则可以将调试状态设置为可变全局变量,并在启动时从主应用程序设置它。这有点像黑客攻击,它的缺点是编译器无法优化未使用的代码路径远离发布版本,但除非发生异常,否则它应该有效。
答案 3 :(得分:3)
更新 - 自发布之日起,gradle构建过程取得了很大进展,因此这个答案可能不是推荐的最佳实践,新的更改甚至可能会制造它。请自行决定。
我认为整个项目结构和配置存在一些混乱。假设您有以下build.gradle配置
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
//resources.srcDirs = ['src/main']
//aidl.srcDirs = ['src/main']
//renderscript.srcDirs = ['src/main']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
您的项目文件夹结构应如下所示
project_root
-src
-main
-java
-com
-example
-build-types
-debug
-java
-com
-example
-FooBar.java
-release
-java
-com
-example
-FooBar.java
FooBar.java
不得在prooject_root/src/main/java/com/example
。它必须位于debug
和release
文件夹中,该文件夹位于src
文件夹之外但位于build-types
文件夹中。这是由setRoot('build-types/*****')
方法配置的。很多人因为看到'debug / java'和'main / java'而感到困惑,后者在演示中以'src / main / java'的方式引用,最后在src中放入'debug / java',错文件夹。我希望这有帮助。
对于涉及其他图书馆的更复杂的环境,您可以在https://stackoverflow.com/a/19918834/319058
查看我的答案答案 4 :(得分:0)
对于您自己提到的库项目,这是不可能的。
您可以将库项目更改为应用程序项目。这似乎工作正常(至少在理论上,我自己没有测试过)。
另一种方法是在应用程序项目中覆盖该类。在进行合并时,将选择您的应用程序项目类,并且您将获得这些值。
答案 5 :(得分:0)
正如Scott所指出的,这是 Gradle 的一个众所周知的缺点。作为一种变通方法,您可以使用此方法,该方法使用反射从应用程序(而不是库)获取字段值:
/**
* Gets a field from the project's BuildConfig. This is useful when, for example, flavors
* are used at the project level to set custom fields.
* @param context Used to find the correct file
* @param fieldName The name of the field-to-access
* @return The value of the field, or {@code null} if the field is not found.
*/
public static Object getBuildConfigValue(Context context, String fieldName) {
try {
Class<?> clazz = Class.forName(context.getPackageName() + ".BuildConfig");
Field field = clazz.getField(fieldName);
return field.get(null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
要获取DEBUG
字段,例如,只需从Activity
调用此字段:
boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");
我也在AOSP Issue Tracker上分享了这个解决方案。