使用Gradle构build库项目时,BuildConfig.DEBUG始终为false

当我在debugging模式下运行我的应用程序时,BuildConfig.DEBUG不起作用(=逻辑上设置为false)。 我使用gradle构build。我有一个库项目,我在做这个检查。 BuildConfig.java在build debug文件夹中看起来像这样:

/** Automatically generated file. DO NOT MODIFY */ package common.myProject; public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); } 

并在发布文件夹中:

 public static final boolean DEBUG = false; 

无论是在图书馆项目还是在应用项目中。

我试图通过检查一个variables来设置我的项目类。 这个类inheritance自库,并在启动时启动。

 <application android:name=".MyPrj" ... 

这导致了另一个问题:在应用程序类之前运行的DataBaseProvider中使用我的DEBUGvariables。

这是预期的行为。

图书馆项目只发布他们的版本变体供其他项目或模块使用。

我们正在解决这个问题,但这不是微不足道的,需要大量的工作。

您可以通过https://code.google.com/p/android/issues/detail?id=52962来跟踪此问题;

使用Android Studio 1.1并且在1.1版本中也可以使用gradle版本:

图书馆

 android { publishNonDefault true } 

应用

 dependencies { releaseCompile project(path: ':library', configuration: 'release') debugCompile project(path: ':library', configuration: 'debug') } 

完整的文档可以在这里findhttp://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

编辑

这个问题刚刚被标记为固定的Android Studio Gradle版本3.0。 在那里你可以使用implementation project(path: ':library') ,它会自动select正确的configuration。

检查imports ,有时BuildConfig是无意中从任何类库导入的。 例如:

 import io.fabric.sdk.android.BuildConfig; 

在这种情况下, BuildConfig.DEBUG将总是返回false ;

 import com.yourpackagename.BuildConfig; 

在这种情况下, BuildConfig.DEBUG将会返回你真正的构build变体。

这就像菲尔的答案,除了它不需要上下文:

 private static Boolean sDebug; /** * Is {@link BuildConfig#DEBUG} still broken for library projects? If so, use this.</p> * * See: https://code.google.com/p/android/issues/detail?id=52962</p> * * @return {@code true} if this is a debug build, {@code false} if it is a production build. */ public static boolean isDebugBuild() { if (sDebug == null) { try { final Class<?> activityThread = Class.forName("android.app.ActivityThread"); final Method currentPackage = activityThread.getMethod("currentPackageName"); final String packageName = (String) currentPackage.invoke(null, (Object[]) null); final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig"); final Field DEBUG = buildConfig.getField("DEBUG"); DEBUG.setAccessible(true); sDebug = DEBUG.getBoolean(null); } catch (final Throwable t) { final String message = t.getMessage(); if (message != null && message.contains("BuildConfig")) { // Proguard obfuscated build. Most likely a production build. sDebug = false; } else { sDebug = BuildConfig.DEBUG; } } } return sDebug; } 

作为解决方法,您可以使用此方法,它使用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。

您可以使用Gradle为每个构buildtypes创build自己的BuildConfig类

 public class MyBuildConfig { public static final boolean DEBUG = true; } 

/src/debug/…/MyBuildConfig.java和…

 public class MyBuildConfig { public static final boolean DEBUG = false; } 

/src/release/…/MyBuildConfig.java

然后使用:

 if (MyBuildConfig.DEBUG) Log.d(TAG, "Hey! This is debug version!"); 

这是另一个解决scheme。

1)创build一个界面

 public interface BuildVariantDetector { boolean isDebugVariant(); } 

2)在Application类上使用这个接口(Appplication模块)

 public class MyApplication extends Application implements BuildVariantDetector { @Override public boolean isDebugVariant() { return BuildConfig.DEBUG; //application (main module) Buildonfig } } 

3)然后在库模块中:

 boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant(); 

我们有同样的问题。 我想出了这样的事情:

我们有一个SDK(库)和一个演示项目,层次结构如下所示:

 Parent | + SDK (:SDK) | + DemoApp (:DemoApp) 

对于我们的演示应用程序,有:SDK:jarjarDebug:SDK:jarjarRelease是一些特定的任务:SDK产生一些后处理的jar子的:SDK

 dependencies { debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files ... more dependencies ... } 

即使对于一次构build的多个buildTypes 。 debugging虽然有点困难。 请给出意见。

不是真正正确的方法来检查你是否在debugging风格,但你可以检查应用程序本身是否可debugging通过:

 private static Boolean sIsDebuggable; public static boolean isDebuggable(Context context) { if (sIsDebuggable == null) sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; return sIsDebuggable; } 

应用程序和库的默认行为将完美匹配。

如果您需要更好的解决方法,则可以使用此替代方法:

 public static boolean isInDebugFlavour(Context context) { if (sDebugFlavour == null) { try { final String packageName = context.getPackageName(); final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig"); final Field DEBUG = buildConfig.getField("DEBUG"); DEBUG.setAccessible(true); sDebugFlavour = DEBUG.getBoolean(null); } catch (final Throwable t) { sDebugFlavour = false; } } return sDebugFlavour; } 

你可以在每个项目的buildTypes上试试这个:

 parent.allprojects.each{ project -> android.defaultConfig.debuggable = true} 

在我的情况下,我导入了错误的BuildConfig因为我的项目有很多库模块。 解决的办法是为我的app模块导入正确的BuildConfig

这是我的解决方法:反映应用程序模块的BuildConfig:

public static boolean debug = isDebug();

 private static boolean isDebug() { boolean result = false; try { Class c = Class.forName("com.example.app.BuildConfig"); Field f = c.getField("DEBUG"); f.setAccessible(true); result = f.getBoolean(c); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return result; }`