BuildConfig.DEBUG与ApplicationInfo.FLAG_DEBUGGABLE的区别

13

获取AndroidManifest中"debuggable"值的方法?所述,检查构建版本是否为可调试的有两种选项:

1.) 使用BuildConfig.DEBUG标志

 if (BuildConfig.DEBUG)`

2.) ApplicationInfo.FLAG_DEBUGGABLE

2.) ApplicationInfo.FLAG_DEBUGGABLE
 if (0 != (getContext().getApplicationInfo().flags & 
     ApplicationInfo.FLAG_DEBUGGABLE))

它们是否完全相同,还是存在区别?在何时使用哪个?

4个回答

12

它们不是完全相同的。

可能会有许多buildType,但debugrelease是强制性的。如果当前选择的构建类型是debug,则BuildConfig.DEBUG将为true,否则它将为false(请参见下面的排除情况)。

ApplicationInfo.FLAG_DEBUGGABLE对应以下内容:


    buildTypes {
        debug {
            debuggable true
        }
... }

现在,ApplicationInfo.FLAG_DEBUGGABLE将会是true

因此,您可以得出以下结论:


    构建类型 {
        调试 {
            debuggable false
        }
... }

有趣的是,尽管您处于debug构建类型中,BuildConfig.DEBUG将变为false


当Debuggable为false时,调试有什么用处? - Elye

5

在这里找到了一篇好文章:http://tekeye.biz/2013/android-debug-vs-release-build

我也进行了测试。如果我们在清单应用程序中强制使用android:debuggable="false"android:debuggable="true",它会发出警告:

 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.

在默认情况下,ApplicationInfo.FLAG_DEBUGGABLE的行为与BuildConfig.DEBUG相同,除非通过更改android:debuggable进行覆盖,这并不是建议的做法。

BuildConfig.DEBUG相比,ApplicationInfo.FLAG_DEBUGGABLE是一种更可靠的检查调试构建的方法,因为在较低的依赖模块中,它无法访问父模块的BuildConfig.DEBUG,并且可能具有不同的值。

例如,应用程序使用MyLib模块。 应用程序的BuildConfig.DEBUG可能为false,但是MyLib的BuildConfig.DEBUG可能为true。 因此,最好使用ApplicationInfo.FLAG_DEBUGGABLE进行检查。


2

在我们的应用经过渗透测试后,一个突显出这些标志使用差异的领域就是渗透测试报告指出攻击者可以利用一种称为“hooking”的技术,其中应用被重新编译,android:debuggable标志更改为true(我不完全确定如何操作)。

他们检测到这种情况的建议是添加以下代码:

"最初的回答"

if (!BuildConfig.DEBUG) {
        try {
            ApplicationInfo appInfo = getPackageManager().getApplicationInfo("uk.co.myapp", 0);
            if ((appInfo.flags & appInfo.FLAG_DEBUGGABLE) != 0) {
                // App has been compromised 
                finish();
                return;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

当你检测到这种情况时,你可以根据自己的需求来处理。我将它添加到了启动活动中,如果触发了,就会显示一条消息,然后执行finish()语句。"Original Answer"翻译成"最初的答案"。

1
我的经验是,BuildConfig.DEBUG 总是与 gradle 文件中的 debuggable 构建属性相关联。
buildTypes {
    debug {
        debuggable true
    }
    debug {
        debuggable false
    }

    ...
}

这也得到了文档的支持:

  • boolean DEBUG - 如果构建是可调试的。

在Gradle构建系统和Android Studio取代Eclipse约在2015年之前,getContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE很可能是确定构建是否可调试的唯一方法。

使用BuildConfig.DEBUG,因为它解析为一个常量,可以在编译过程中用于优化代码。


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