ADT何时将BuildConfig.DEBUG设置为false?


110

在最新版本的ADT(r17)中,添加了一个生成的常量,BuildConfig.DEBUG该常量根据构建类型进行设置。我的问题是,它永远不会设置为false,我希望在执行“ Android Tools-> Export Signed Application Package”时会更改它,但它不适用于我。

那么,如何更改构建类型?

添加了一项功能,使您只能在调试模式下运行某些代码。现在,生成会生成一个名为BuildConfig的类,其中包含一个DEBUG常量,该常量会根据您的生成类型自动设置。您可以在代码中检查(BuildConfig.DEBUG)常量以运行仅调试功能


2
BuildConfig.java由Android构建工具自动生成,并放置在gen文件夹中。已签名的APK应该具有BuildConfig.DEBUG = false。对您来说应该不成问题。您不必手动触摸该文件...
IgorGanapolsky 2013年

1
如果使用gradle释放,则此标志是100%可靠的。因此,当您执行./gradlew assembleDebug时,它的值为true,而当执行assembleRelease其false时。
老虎机

Answers:


56

当前,您可以通过禁用“自动构建”,清理项目然后通过“ Android工具->导出签名的应用程序包”导出来获得正确的行为。当您运行该应用程序时,BuildConfig.DEBUG应该为false。


也坏了。结果是显示所有Log.d消息,该标志应忽略这些消息。ps。在哪里提交错误报告?
tomi 2013年

即使调试,我的也总是假的
相信

39

使用Eclipse时,我总是在导出发行版中的应用程序之前禁用“自动构建”选项。然后,我清理项目并导出。否则它将开始在调试模式下编译,然后BuildConfig.DEBUG的值可能是错误的。

使用Android Studio,我只需在build.gradle中添加自己的自定义变量:

buildTypes {
    debug {
        buildConfigField "Boolean", "DEBUG_MODE", "true"
    }
    release {
        buildConfigField "Boolean", "DEBUG_MODE", "false"
    }
}

当我构建项目时,BuildConfig.java生成如下:

public final class BuildConfig {
  // Fields from build type: debug
  public static final Boolean DEBUG_MODE = true;
}

然后在我的代码中可以使用:

if (BuildConfig.DEBUG_MODE) {
    // do something
}

切换调试/发布版本后,我建议进行清理。


1
如果您使用proguard,则此解决方案是最好的,因为它将生成带有文字值的常量,因此在发布模式下,调试代码将从二进制文件中完全删除。
Victor Laerte

33

它无法正常工作:

问题27940:对于导出的应用程序包,BuildConfig.DEBUG为“ true”

令人失望的是,他们有时会发布错误的功能。


9
如果要解决此问题,请转到上面提到的问题的链接并“加注星标”。
盖伊

11

它确实有效,但是请注意,即使导出已签名的文件,代码文件也不会更改。导出过程将该变量的值更改为false,这可能会给您错误的印象,即它不起作用。我用日志记录语句进行了测试,例如

if (com.mypackage.BuildConfig.DEBUG)
            Log.d(TAG, location.getProvider() + " location changed");

测试时,我的Log语句不再产生任何输出。


1
你到底是做什么的?
pbhowmick 2013年

2
我将BuildConfig.DEBUG的实例更改为com.mypackage.BuildConfig.DEBUG,然后重新运行该应用程序……它仍然始终返回true。也许我误解了你的建议。
克里斯·雷

1
我的意思是代码不会更改。但是,com.mypackage.BuildConfig.DEBUG将在编译后设置为False。尝试执行上述测试日志记录语句(选择要记录的任意字符串),执行导出,然后运行它。查看adb是否显示日志记录语句。我敢打赌,adb将不会报告该日志记录语句,这表明DEUBUG已设置为false。
pbhowmick 2013年

1
我不确定我是否了解“代码”的含义...但是,我会说,在导出APK之前进行清理(按照接受的答案中的建议)会使BuildConfig.DEBUG和com.mypackage.BuildConfig .DEBUG报告为预期的错误。
克里斯·雷

你说对了。这是预期的行为。
pbhowmick

10

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

import io.fabric.sdk.android.BuildConfig;

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

import com.yourpackagename.BuildConfig;

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

ps我只是从我的答案中复制了此内容:使用gradle构建库项目时,BuildConfig.DEBUG始终为false


1
是的,对我来说,它是偶然从进口的android.support.compat。我想这是用不同名称定义自己的字段的另一个原因。
arekolek

5

准备发布

关闭日志记录和调试

在构建要发布的应用程序之前,请确保禁用日志记录并禁用调试选项。您可以通过删除对源文件中Log方法的调用来停用日志记录。您可以通过从清单文件中的标记中删除android:debuggable属性,或在清单文件中将android:debuggable属性设置为false来禁用调试。另外,删除项目中创建的所有日志文件或静态测试文件。

另外,您应该删除添加到代码中的所有Debug跟踪调用,例如startMethodTracing()和stopMethodTracing()方法调用。

更多信息请点击链接。


1
我认为此过程现在会在构建时自动发生:developer.android.com/tools/sdk/tools-notes.html
IgorGanapolsky 2013年

导致编译时错误:«避免对调试模式进行硬编码;省略它可以允许调试和发布版本自动分配一个»
Nikita Bosik

5

我的解决方案:

  1. 项目->自动构建
  2. 项目->清洁
  3. 项目->构建
  4. Project Export Android应用程序

它在r20中工作


1
刚才对我有用(我猜是使用最新的ADT)。不确定清洁是否可以解决问题。
强尼

3

如果您在APK导出过程中使用proguard,我想提出一个简单的解决方法。

Proguard提供了一种在释放模式下删除对特定功能的调用的方法。可以使用中的以下设置删除对调试日志的任何调用proguard-project.txt

# Remove debug logs
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

以及中的优化设置project.properties

proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt

这样,您就不必担心@Jeremyfa指向调试日志传递的任何不必要的String计算。计算仅在发布版本中删除。

因此,BuildConfig.DEBUG的解决方法使用了与proguard相同的功能,如下所示。

public class DebugConfig {

    private static boolean debug = false;

    static {
        setDebug(); // This line will be removed by proguard in release.
    }

    private static void setDebug() {
        debug = true;
    }

    public static boolean isDebug() {
        return debug;
    }
}

然后在中进行设置proguard-project.txt

-assumenosideeffects class com.neofect.rapael.client.DebugConfig {
    private static *** setDebug();
}

我宁愿使用此Build Automatically选项来禁用该选项,因为这不依赖于构建器的单个IDE设置,而是作为开发者之间共享的提交文件进行维护。


1

据我所知,它无法正常工作(Android问题22241

我在一个项目(使用Eclipse)上遇到了一些麻烦,在导出我的项目的签名APK时,该常数未设置为true :(

很想听听它的工作原理


1
它应该已经在r17中修复,在bug跟踪器中已将其标记为r17。
smith324 2012年

1
实际上,导出时,lib在ADT中不是以发布模式编译的(在Ant中工作)。我更新了code.google.com/p/android/issues/detail?id=27940
Xavier Ducrohet

1
@Xav感谢您的调查,现在我保证不再向您发送垃圾邮件。实际上,这是我遇到问题的主要项目(没有研究依赖库)。如果我可以创建一个具体的测试用例,则将其发布到同一问题下的Bug跟踪器中。
smith324 2012年

1

一个好的方法是创建自己的课程:

public class Log {

public static void d(String message) {
    if (BuildConfig.DEBUG)
        android.util.Log.d(
            "[" + (new Exception().getStackTrace()[1].getClassName()) + "]",
            "{" + (new Exception().getStackTrace()[1].getMethodName()) + "} "
            + message
        );
}

}

12
这种方法的问题在于,当DEBUG为false时,java仍将计算每个String并将其传递给您的自定义类。if(DEBUG)Log.d(...)不太优雅,但效率更高。
Jeremyfa

0

当BuildConfig中的值设置为最终值时,我已经看到了一些奇怪的行为。这可能与您的问题有关。

简单的解释是,默认值是在运行Proguard之前首先设置的,然后在运行Proguard之后,将使用适当的值重新生成BuildConfig文件。但是,到目前为止,Proguard已经优化了您的代码,您遇到了问题。

这是我针对Gradle创建的错误。 https://code.google.com/p/android/issues/detail?id=182449

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.