在Android中为Gradle中的库项目构build变体

我正在尝试使用Gradleconfiguration一个包含一些外部库的项目。 使用Gradle,我可以使用Build Variants为主应用程序设置不同的环境configuration(在configuration文件中有一个类),这样我就可以根据这个variables执行代码。

问题是我怎样才能为图书馆项目做同样的事情? 我为这个项目创build了这个库,我想为不同的场景设置不同的Build Variants。

例如:在库中,当以debugging模式运行时,打印所有日志,以便在开发时看到它们。 在发行模式不要。

文件的结构:

src ----- > debug -> java -> config -> PlayerEnvConfig main -> com.mypackagename -> etc... release -> java -> config -> PlayerEnvConfig 

代码在debugging:包configuration;

 /** * 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; } 

问题是,对于主项目,我可以使用这个Buildtypes为不同的场景configuration不同的应用程序,但是我怎样才能为Library Project做同样的事情呢?

因为从我在http://tools.android.com/tech-docs/new-build-system/user-guide中读到的那一刻,库只会在testing时使用debugging模式。

有任何想法吗?

谢谢!

Solutions Collecting From Web of "在Android中为Gradle中的库项目构build变体"

这是来自谷歌代码问题的@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

不知道你的configuration有什么问题,但关于你的需求,我会做不同的。

在gradle构build文件中,您可以使用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>" 

这在https://code.google.com/p/android/issues/detail?id=52962中有logging&#x3002; 正如你发现的那样,构buildtypes不会传播到库项目,并没有一个很好的解决方法。 如果您可以控制库项目的代码,则可以将debugging状态设置为可变的全局variables,并在启动时将其设置为主应用程序。 这是一个黑客,它有缺点,编译器不能优化未使用的代码path从版本构build,但除非有什么不寻常的事情发生,它应该工作。

更新 – 从本文发布之时起,在gradle构build过程中已经有了很多进展,因此这个答案可能不是推荐的最佳实践,新的变化甚至可能会使之瘫痪。 使用你自己的判断力。

我相信在整个项目结构和configuration方面有一点困惑。 假设您有以下build.gradleconfiguration

 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 。 它必须在debugrelease文件夹,它是驻留在src文件夹之外,但是在build-types文件夹内。 这是由setRoot('build-types/*****')方法configuration的。 很多人看到'debug / java'和'main / java',其中后者以“src / main / java”的forms被引用,最后把'debug / java'放在src中,错误的文件夹 我希望这个帮助。

对于涉及其他库的更复杂的环境,你可以在这里查看我的答案https://stackoverflow.com/a/19918834/319058

像你自己提到的那样,图书馆项目是不可能的。

您可以将库项目更改为应用程序项目。 这似乎工作正常(至less在理论上,我没有testing它自己)。

另一种方法是在应用程序项目中重写该类。 您的应用程序项目类将在合并发生时select,您将可以使用这些值。

正如Scott指出的那样,这是Gradle的一个已知缺点。 作为解决方法,您可以使用此方法,它使用reflection从应用程序(而不是库)中获取字段值:

 /** * 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问题跟踪器上分享了这个解决scheme。