我如何检测是否处于发布或调试模式?

487

如何在我的代码中检测是Release模式还是Debug模式?

10个回答

947

最简单、最好的长期解决方案是使用 BuildConfig.DEBUG。这是一个布尔值,对于 debug 版本将为 true,否则为 false

if (BuildConfig.DEBUG) {
  // do something for a debug build
}

有报道称,Eclipse构建的价值并非100%可靠,但我个人没有遇到问题,因此我无法确定它到底有多大问题。

如果您使用的是Android Studio,或者如果您正在使用Gradle从命令行运行,则可以将自己的东西添加到BuildConfig中或以其他方式调整debugrelease 构建类型以帮助在运行时区分这些情况。

Illegal Argument的解决方案基于清单中android:debuggable标志的值。如果您希望通过这种方式区分“调试”构建和“发布”构建,则按照定义,这是最佳解决方案。但是,请记住,从现在开始,debuggable标志实际上是一个独立的概念,与Gradle / Android Studio认为的“debug”构建不同。任何构建类型都可以选择将debuggable标志设置为对该开发人员和该构建类型有意义的任何值。


39
BuildConfig is located in your app's package, e.g. import com.mycompany.myapp.BuildConfig; - Chris Cirefice
16
由于AndroiStudio中的一个错误,这个功能不再起作用了,即使在DEBUG模式下也是false。 - user387184
2
我正在使用v1.2.2版本,而BuildConfig.DEBUG始终为false,然后我尝试了下面的建议,它对我有效-我也会尝试你的建议-非常感谢! - user387184
4
事实证明,在使用库时,这种方法行不通(始终返回 true):https://dev59.com/RGIj5IYBdhLWcg3whFYI 。想知道最佳替代方案是什么。 - android developer
3
这个答案对于库项目(.aar)无效。 - Lavekush Agrawal
显示剩余11条评论

90
尝试以下方法:
boolean isDebuggable =  ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );

Kotlin:

val isDebuggable = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE

这段内容来自于(链接在此)


11
无论是库项目还是应用程序项目,这个答案都适用。 - Lavekush Agrawal
getApplicationInfo().flags需要导入什么? - A1m
3
好的,这段内容的翻译如下:在静态上下文中它就是无效的,详见 https://dev59.com/Imgv5IYBdhLWcg3wYv2i。 - A1m
不需要任何导入:if ((getApplicationInfo().flags & android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0)。如果您正在编写库并且不想不断修改文件以引用应用程序的包,这很好。但是需要上下文。 - Al Ro

76

是的,您使用以下内容不会有任何问题:

if (BuildConfig.DEBUG) {
   //It's not a release version.
}

除非你导入了错误的BuildConfig类。确保你正在引用你项目的BuildConfig类,而不是任何依赖库中的。

在此输入图片描述


2
“除非您导入了错误的BuildConfig类”……是的,非常好的观点:D - Benjamin Piette
谢谢!这就是我项目中的问题,它在某种程度上选择了库项目的BuildConfig(直到Android Studio 3发布之前始终是发布模式)。 - Amit Garg
我在Flutter中遇到了“未定义的BuildConfig类”错误。 - Kamlesh
如果我确实在项目的不同模块中怎么办?例如,我为其他应用程序制作SDK并希望检查它? - android developer

47

由于BuildConfig.DEBUG存在不一致的评论,我使用以下方法在调试模式下禁用了Crashlytics(和分析):

更新/app/build.gradle文件

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.1"

    defaultConfig {
        applicationId "your.awesome.app"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 100
        versionName "1.0.0"
        buildConfigField 'boolean', 'ENABLE_CRASHLYTICS', 'true'
    }
    buildTypes {
        debug {
            debuggable true
            minifyEnabled false
            buildConfigField 'boolean', 'ENABLE_CRASHLYTICS', 'false'
        }
        release {
            debuggable false
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

然后,在您的代码中,您可以按照以下方式检测ENABLE_CRASHLYTICS标志:


    if (BuildConfig.ENABLE_CRASHLYTICS)
    {
        // enable crashlytics and answers (Crashlytics by default includes Answers)
        Fabric.with(this, new Crashlytics());
    }

在您的应用中使用相同的概念,并将ENABLE_CRASHLYTICS重命名为任何您想要的内容。我喜欢这种方法,因为我可以在配置中看到标志并控制标志。


你不应单独调用Crashlytics和Answers。只需要使用以下代码: Fabric.with(this, new Crashlytics());来同时包含Crashlytics和Answers。 - Mike Bonnell
1
谢谢,@MikeBonnell,我已经对示例代码进行了代码更改。 - Someone Somewhere
我不明白这与使用BuildConfig.DEBUG有何不同 - 如果您仅为调试版本设置BuildConfig.ENABLE_CRASHLYTICS,那么BuildConfig.DEBUG和BuildConfig.ENABLE_CRASHLYTICS的值始终相同,对吗? - k2col
我认为开发库项目的开发人员在使用BuildConfig.DEBUG时,可能会遇到检测调试/发布版本的问题。这可能也涉及到早期Android Studio的一个bug... - Someone Somewhere

23

或者,您可以使用 BuildConfig.BUILD_TYPE 进行区分;

如果您正在运行调试版本,则 BuildConfig.BUILD_TYPE.equals(“debug”); 返回 true。对于发布版本,BuildConfig.BUILD_TYPE.equals(“release”); 返回 true。


2
这是正确的答案。返回“release”,而BuildConfig.DEBUG始终返回true - Minas Mina
我在Flutter中遇到了一个“未定义的BuildConfig类”错误。 - Kamlesh
这个页面上唯一百分之百有效的建议!(鼓掌表情) - undefined

15

我使用这个解决方案来判断我的应用程序是否在调试版本上运行。

if (BuildConfig.BUILD_TYPE.equals("debug")){
   //Do something
}

1
请在您的答案中添加描述。这比只有一段代码更有帮助。 - Mathews Sunny
我在一个依赖的gradle模块中使用了if (BuildConfig.DEBUG) {},该模块当然没有引用到应用程序的build.gradle文件 - 这导致调试模式被错误地识别。 if (BuildConfig.BUILD_TYPE.equals("Debug")){ }修复了这个问题。谢谢。 - kosiara - Bartosz Kosarzycki
这是真正的答案,请将“Debug”更改为“debug”。 - Jetwiz
1
@Kamlesh 在撰写这篇答案时,Flutter 还没有出现在我们的视野中。请注意这一点。 - Giedrius Šlikas
这很接近了,但不要在代码中硬编码构建变体的名称。请参见下面的其他答案,并确保导入正确的BuildConfig。 - Nicolas Mage
显示剩余2条评论

8
if (BuildConfig.DEBUG) { 



}

这对我有用


6
你需要在gradle/kts文件中使用这个,这样BuildConfig文件就会为你生成:
buildFeatures {
   buildConfig = true
}

然后,找到属于您应用程序包名称的字段BuildConfig.DEBUG
类似于以下这种方式(不建议使用,因为在创建发布版本时不会删除代码),可以检查应用程序是否可调试:
val isDebuggable = context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0

4
请确保导入的是正确的BuildConfig类。 同时,您可以放心使用以下代码:
if (BuildConfig.DEBUG) {
   //It's not a release version.
}

正确的导入方式是 <package_name>.BuildConfig - CoolMind
对我来说没用。在Flutter中,我遇到了一个错误:未定义的BuildConfig类。 - Kamlesh

0

Build.IS_DEBUGGABLE可能是正确的。它来自于"ro.debuggable"


如果发布版本因某种原因被制作成可调试版本呢? - android developer
@androiddeveloper 可以将发布版本制作为可调试的吗? - Khalid Lakhani
1
@KhalidLakhani 我很确定它可以。 - android developer
1
@KhalidLakhani 不仅如此,一个调试版本的构建也可以是不可调试的。 - android developer
@androiddeveloper明白了,像这样构建类型{ debug { debuggable true } release { debuggable false
}
- Khalid Lakhani
1
@KhalidLakhani 的确。虽然对于非调试版本来说,让它不可调试会有些奇怪 :) - android developer

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