10

正如从代码中获取 androidManifest 的“可调试”值所指的那样?,有两种检查构建是否可调试的选项:

1.) BuildConfig.DEBUG 标志

 if (BuildConfig.DEBUG)`

2.) ApplicationInfo.FLAG_DEBUGGABLE

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

它们是两个相同的,还是不同的?什么时候用什么?

4

4 回答 4

11

它们不相同。

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

ApplicationInfo.FLAG_DEBUGGABLE对应于以下:


    buildTypes {
        debug {
            debuggable true
        }

        ...
    }

现在,ApplicationInfo.FLAG_DEBUGGABLEtrue

因此,您可以得出结论,您可以执行以下操作:


    buildTypes {
        debug {
            debuggable false
        }

        ...
    }

有趣的是,虽然你是debugbuild 类型,但BuildConfig.DEBUG会变成false.

于 2017-08-11T14:27:36.597 回答
4

在这里找到一篇好文章: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父模块的 ,并且可能具有不同的值。

例如 App 使用 MyLib 模块。AppBuildConfig.DEBUG可能是假的,但 MyLibBuildConfig.DEBUG可能是真的。因此最好检查使用ApplicationInfo.FLAG_DEBUGGABLE

于 2017-08-11T15:18:52.207 回答
2

一个突出显示这些标志用法差异的领域是对我们的应用程序进行渗透测试。渗透测试报告向我们指出,攻击者可以使用一种称为“挂钩”的技术,在重新编译应用程序时将 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() 语句。

于 2019-04-16T08:42:12.033 回答
0

我的经验是,BuildConfig.DEBUG它总是与debuggablegradle 文件中的 build 属性相关联。

buildTypes {
    debug {
        debuggable true
    }
    debug {
        debuggable false
    }

    ...
}

文档也支持这一点:

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

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

使用BuildConfig.DEBUG是因为它解析为一个常量,可以在编译期间使用它来优化代码。

于 2017-10-25T15:49:01.550 回答