BuildConfig.DEBUG总是假的建设有gradle这个库项目时

问题描述 投票:80回答:13

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

/** Automatically generated the 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;

无论是在库项目,并在应用程序项目。

我试图通过检查被设置一类我的项目的一个变量来解决这个问题。这个类从库中继承并开始启动时。

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

这就引出了另一个问题:那是我用我的DEBUG变量在应用程序类之前运行的DataBaseProvider,并且由于这个错误将无法正常运行。

android gradle android-library
13个回答
51
投票

这是预期的这种行为。

库项目只能通过其他项目或模块发布消费释放他们的变种。

我们在解决这个工作,但是这是不容易,而且需要工作显著量。

您可以跟踪在https://code.google.com/p/android/issues/detail?id=52962问题


1
投票

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

`公共静态布尔调试= 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;
}`

0
投票

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

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

0
投票

以我为例,我作为导入我的项目库有很多模块错BuildConfig。此修复程序是导入正确BuildConfigapp模块。


0
投票

与可调试的gradle中真正的文件工作。

buildTypes {
  demo{
 debuggable true
    }
  live{
 debuggable true
    }
}

0
投票

BuildConfig.DEBUG是不可靠的可言,Android已经提供的内部标志,是全球可用的指示,如果构建处于调试或非调试模式

(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0) 

如果是在调试将是真实的

积分:https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da1098120


86
投票

借助Android 1.1工作室,并且还具有在1.1版本的Gradle是可能的:

图书馆

android {
    publishNonDefault true
}

应用

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

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

编辑:

issue刚刚被标记为固定为Android Studio的摇篮3.0版。在那里,你可以只使用implementation project(path: ':library'),它会自动选择正确的配置。


40
投票

检查imports,有时BuildConfig从任何类库的无意引进。例如:

import io.fabric.sdk.android.BuildConfig;

在这种情况下BuildConfig.DEBUG将始终返回false;

import com.yourpackagename.BuildConfig;

在这种情况下BuildConfig.DEBUG将返回你真正构建变量。


7
投票

这是菲尔的回答,除了它不需要背景:

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

6
投票

作为一种变通方法,您可以使用此方法,它使用反射来从应用程序(而不是库)获取字段值:

/**
 * 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这个解决方案。


5
投票

不是真的按正确的方式,如果你在调试的味道,但你可以检查,如果应用程序本身是通过调试的:

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

2
投票

你可以创建自己的BuildConfig类的gradle使用每个构建类型

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!");

2
投票

这是另一种解决方案。

1)创建的接口

public interface BuildVariantDetector {

    boolean isDebugVariant();

}

2)使用的应用类(应用模块在此接口)

public class MyApplication extends Application implements BuildVariantDetector {

    @Override
    public boolean isDebugVariant() {
        return BuildConfig.DEBUG; //application (main module) Buildonfig
    }

}

3),然后在库模块:

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

1
投票

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

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

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

对于演示程序,我们有,是:SDK:jarjarDebug:SDK:jarjarRelease:SDK一些特定的任务产生了一些后处​​理罐:

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

这适用即使在一旦建成多个buildTypes。调试是有点困难,但。请评论。

© www.soinside.com 2019 - 2024. All rights reserved.