Android开发过程中通常我们区分debug和release的相关配置都会采用
BuildConfig.DEBUG
来进行判断,殊不知这个东西弄不好却是一个坑,刚好在最近的开发过程中遇到。
问题
最近在负责一个内部系统,需要根据
BuildConfig.DEBUG
来判断相关入参,debug模式主要供QA进行demo环境测试,release模式主要用于模拟线上真实环境和回归。但是发现,无论怎么调,
BuildConfig.DEBUG
始终都是true,也就是release模式下还是true,这就属于bug了,这个问题必须要解决的,因为项目中使用
BuildConfig.DEBUG
还是很频繁。
分析
再找不到任何头绪的时候开始google和baidu,发现均是
BuildConfig.DEBUG
始终为false的问题,刚好和我遇到的这个相反,并且一篇文章满天飞,很是费解。
我开始研究他们的原因,有两种说法:
- 当项目中有很多module时并且有很多相互依赖,编译的时候因为每个module都会生成一个BuildConfig文件,因为相互依赖,这些BuildConfig都可以看到,也就是说,有可能你导包导错了,导入不是自己当前模块下的BuildConfig。但是这种几乎也不会出错,因为编译的时候所有的module都是跟随编译环境更换debug模式或者release模式,除非你在哪里做了骚操作,把被依赖的那个module下的BuildConfig.DEBUG值改掉了。
- 在调试代码时因为
在debug模式和release模式间进行切换,编译器没有及时同步Gradle,导致BuildConfig.DEBUG的值没能更改。当然这种情况也不太容易发生,如果Gradle一直不同步那我们的编译环境也会出现问题。Build Variants
最终原因
经过上边的两种情况都进行了验证,并且都淘汰掉了。接下来我在build.gradle下buildTypes下查找时忽然发现一个字段
debuggable true
,debug和release模式的配置都是这个。

开始怀疑,通过google查清,
debuggable
主要用于应用在当前编译模式下是否可以进行调试。以下是引用官方的说明:
Whether or not the application can be debugged, even when running on a device in user mode — “true” if it can be, and “false” if not. The default value is “false”.
这个字段就是引发此次Bug的罪魁祸首,他可以直接影响BuildConfig.DEBUG和ApplicationInfo.FLAG_DEBUGGABLE的值,并且是等同的。
debuggable
除了可以配置在gradle中,也可以配置在manifest的application的闭包中,gradle中配置不会提醒报错或警告,但是在manifest中配置直接“报红”了:
google并不建议我们进行这样设置:
Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one less…
It’s best to leave out the android:debuggable attribute from the manifest. If you do, then the tools will automatically insert android:debuggable=true when building an APK to debug on an emulator or device. And when you perform a release build, such as Exporting APK, it will automatically set it to false.
If on the other hand you specify a specific value in the manifest file, then the tools will always use it. This can lead to accidentally publishing your app with debug information.
随便翻译了一下,大概以下两种原因:
- 硬编码导致所有的编译环境不能覆盖,debug和release模式都是相同的值。
- 会影响项目中的BuildConfig.DEBUG导致在release会把一些私密信息打印出来,如果用这种方式去判断和设置值,说不定会出现一些严重的bug,像我开篇遇到的那样。
总结
到此针对BuildConfig.DEBUG值不准确的原因终于弄清楚了。
总之我们在开发中一定要注意以下几点:
- 在多模块相互依赖的情况下,api调用导包一定要导正确。
- 不要随便在gradle或者manifese中设置debuggable的值。
-
如果在gradle中真的需要配置debuggable,可以自己额外再创造一个字段,区分debug和release环境,例如:
在release模式下: 在debug模式下: 然后在项目中直接引用
即可,这样始终是准确的。BuildConfig.IS_DEBUG
参考
- https://developer.android.com/guide/topics/manifest/application-element
- https://stackoverflow.com/questions/45637524/buildconfig-debug-vs-applicationinfo-flag-debuggable
- https://www.trinea.cn/android/android-whether-debug-mode-why-buildconfig-debug-always-false/