使用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; }`