使用gradle构建库项目时,BuildConfig.DEBUG始终为false

use*_*936 81 android gradle android-library

当我在调试模式下运行我的应用程序时,BuildConfig.DEBUG无效(=逻辑设置为false).我用Gradle来构建.我有一个图书馆项目,我在这里检查.BuildConfig.java在构建调试文件夹中看起来像这样:

/** Automatically generated the file. DO NOT MODIFY */
package common.myProject;

public final class BuildConfig {
    public static final boolean DEBUG = Boolean.parseBoolean("true");

}
Run Code Online (Sandbox Code Playgroud)

并在发布文件夹中:

public static final boolean DEBUG = false;
Run Code Online (Sandbox Code Playgroud)

在库项目和应用程序项目中.

我试图通过检查一个设置了我的项目类的变量来解决这个问题.该类继承自库并在启动时启动.

<application
        android:name=".MyPrj" ...
Run Code Online (Sandbox Code Playgroud)

这导致了另一个问题:我在应用程序类之前运行的DataBaseProvider中使用我的DEBUG变量,并且由于此错误它将无法正常运行.

Nik*_*las 86

使用Android Studio 1.1并且还有1.1版的gradle版本可能:

图书馆

android {
    publishNonDefault true
}
Run Code Online (Sandbox Code Playgroud)

应用

dependencies {
    releaseCompile project(path: ':library', configuration: 'release')
    debugCompile project(path: ':library', configuration: 'debug')
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:

问题刚刚被标记为Android Studio Gradle 3.0版已修复.在那里你可以使用implementation project(path: ':library'),它会自动选择正确的配置.

  • 这种方式有效.但是有一个缺点:即使你正在制作":app:assembleDebug",也会调用":library:assembleRelease",这将导致更长的构建时间. (5认同)

Xav*_*het 51

这是预期的行为.

库项目仅发布其版本变体以供其他项目或模块使用.

我们正在努力解决这个问题,但这非常重要,需要大量的工作.

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

  • 解决方法:BuildConfig.DEBUG的instaed在lib-project中创建另一个布尔变量,例如BuildConfig.RELEASE,并将其与应用程序的buildType链接.详细信息:https://gist.github.com/almozavr/d59e770d2a6386061fcb (4认同)

Gen*_*ani 42

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

import io.fabric.sdk.android.BuildConfig;
Run Code Online (Sandbox Code Playgroud)

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

import com.yourpackagename.BuildConfig;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,BuildConfig.DEBUG将返回您的真实构建变体.


Jar*_*ler 7

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

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;
}
Run Code Online (Sandbox Code Playgroud)


Phi*_*hil 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;
}
Run Code Online (Sandbox Code Playgroud)

DEBUG例如,要获得该字段,只需从您的Activity:

boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");
Run Code Online (Sandbox Code Playgroud)

我也在AOSP问题跟踪器上分享了这个解决方案.

  • 可能对其他人有用:小心在Gradle中使用`applicationIdSuffix`会使`.BuildConfig`类无法通过上面的代码访问. (3认同)

and*_*per 5

不是检查你是否处于调试风格的正确方法,但你可以通过以下方式检查应用程序本身是否可调试:

private static Boolean sIsDebuggable;

public static boolean isDebuggable(Context context) {
    if (sIsDebuggable == null)
        sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
    return sIsDebuggable;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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;
}
Run Code Online (Sandbox Code Playgroud)