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

116
在 ADT(r17)的最新版本中,添加了一个生成的常量 BuildConfig.DEBUG,它根据构建类型进行设置。我的问题是它从未被设置为 false,我期望在执行“Android 工具->导出签名应用程序包”时会发生变化,但对我来说并没有发生。

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

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

2
BuildConfig.java是由Android构建工具自动生成的,并放置在gen文件夹中。签名APK应该有BuildConfig.DEBUG = false。这对你来说不应该是个问题。你不需要手动修改那个文件... - IgorGanapolsky
1
如果您使用Gradle进行发布,则此标志的可靠性为100%。因此,当您执行./gradlew assembleDebug时,它为true,而在执行assembleRelease时为false。 - slott
12个回答

56

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


翻译:出现了错误。这将导致显示所有应该被此标志省略的 Log.d 消息。附注:如何提交错误报告? - tomi
我的代码一直是假的,即使在调试时。 - behelit

46

在发布应用程序之前,我总是要在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
你是救命恩人!!!这个解决方案非常完美,无论什么情况下都能正常工作。 - Divesh

34

它无法正常工作:

问题27940:导出的应用程序包中BuildConfig.DEBUG为"true"

令人失望的是,他们有时会发布带有漏洞的功能。


9
请前往上述问题链接并为其加星,如果你想要修复这个问题。 - Guy

18
检查 imports,有时会无意间从库的任何类导入BuildConfig。 例如:
import io.fabric.sdk.android.BuildConfig;

在这种情况下,BuildConfig.DEBUG总是会返回false
import com.yourpackagename.BuildConfig;

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

附言:我只是从这里复制了答案:在使用Gradle构建库项目时,BuildConfig.DEBUG始终为false


1
是的,对我来说它是从android.support.compat意外导入的。我想这是另一个理由,只需使用不同的名称定义自己的字段。 - arekolek
我的项目不允许我从我的包名中导入。Artic Fox IDE 真的很有 bug。 - JPM
我也一样。不小心从 Firebase 导入了。我已经做了这么多个月了!终于找到罪魁祸首了。 - Harshal Karande

11

它确实起作用,但请注意代码文件从未更改,即使在导出签名文件时也是如此。 导出过程将此变量的值更改为 false,这可能会让您产生错误的印象,认为它没有起作用。 我使用类似以下的日志记录语句进行了测试

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

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


2
我将BuildConfig.DEBUG的实例更改为com.mypackage.BuildConfig.DEBUG,然后重新运行了应用程序...但它仍然始终返回true。也许我误解了你的建议。 - Chris Rae
1
我想说的是代码不会改变。但是,编译后com.mypackage.BuildConfig.DEBUG将被设置为False。尝试使用上面的测试日志语句(选择一个任意字符串进行记录),导出并运行它。看看adb是否显示日志语句。我愿意打赌adb不会报告该日志语句,表示已将DEUBUG设置为false。 - pbhowmick
1
我不确定你所说的“代码”是什么意思...但是,我想说在导出APK之前进行清理(如接受的答案中建议的那样),可以使BuildConfig.DEBUG和com.mypackage.BuildConfig.DEBUG都按预期报告为false。 - Chris Rae
你做对了,那是期望的行为。 - pbhowmick
如果您字面上使用“com.mypackage.BuildConfig.DEBUG”,它将无法工作。该包是相对于您的应用程序的。 - Brill Pappin
这是一个需要注意的问题...看一下导入语句,因为很容易导入错误的包,调试信息也不会传递到库中... - Renetik

6

来自发布准备

关闭日志记录和调试

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

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

更多信息请查看链接。


1
我认为这个过程现在已经自动在构建时发生了:http://developer.android.com/tools/sdk/tools-notes.html - IgorGanapolsky
导致编译时错误:「避免硬编码调试模式;省略它可以让调试和发布版本自动分配一个。」 - Nikita Bosik

5
我的解决方案:
  1. 项目 -> 自动构建
  2. 项目 -> 清除
  3. 项目 -> 构建
  4. 项目导出 Android 应用程序
在版本 r20 中有效。

1
这对我刚刚起作用了(我猜是使用最新的ADT)。也许清理解决了它,不确定。 - Jonny

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指向的调试日志中。在发布版本中,这些计算将被移除。

因此,对于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();
}

我更倾向于使用这种方法而不是禁用自动构建选项,因为这不依赖于构建者个人的IDE设置,而是作为提交的文件进行维护,这些文件在开发人员之间共享。


1

您是否检查了应用程序级别的build.gradle文件,将debuggable true更改为发布版本?

buildTypes {
    release {
        debuggable true
        }
     }

"相反,你可以保留false或对该行进行注释。"
buildTypes {
    release {
        //debuggable true
        }
     }

现在您将获得BuildConfig.DEBUG false以进行发布构建。

1

据我所知,它不能正常工作(Android问题22241

在一个项目中(使用Eclipse工作),我遇到了一些麻烦,当导出我的项目的已签名APK时,常量没有设置为true :(

虽然如此,我很想听听它是如何工作的


1
它应该已经在r17中修复了,在错误跟踪器中标记为已修复。 - smith324
1
实际上,在 ADT 导出时(在 Ant 中有效),库不会在发布模式下编译。我更新了 http://code.google.com/p/android/issues/detail?id=27940。 - Xavier Ducrohet
1
@Xav 谢谢你的关注,我保证不再烦你了。实际上,我遇到问题的是主要项目(没有查看依赖库)。如果我能创建一个具体的测试用例,我会在同一问题下将其发布到错误跟踪器中。 - smith324

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接