正如Getting "debuggable" value of androidManifest from code?所提到的,有两种选项可以检查构建是否可调试:
1.)BuildConfig.DEBUG标志
if (BuildConfig.DEBUG)`
2.)ApplicationInfo.FLAG_DEBUGGABLE
if (0 != (getContext().getApplicationInfo().flags &
ApplicationInfo.FLAG_DEBUGGABLE))
它们是两个相同的,还是不同的?什么时候用?
它们不完全相同。
可能有许多buildType
s,但debug
和release
是强制性的。 BuildConfig.DEBUG
将是true
,如果当前选择的构建类型是debug
,否则它将是false
(见下面的排除案例)。
ApplicationInfo.FLAG_DEBUGGABLE
对应于以下内容:
buildTypes {
debug {
debuggable true
}
...
}
现在,ApplicationInfo.FLAG_DEBUGGABLE
将是true
。
因此,您可以得出结论,您可以执行以下操作:
buildTypes {
debug {
debuggable false
}
...
}
有趣的是,虽然你在debug
构建类型,BuildConfig.DEBUG
将成为false
。
在这里找到一篇好文章:http://tekeye.biz/2013/android-debug-vs-release-build。
也测试了它。如果我们在Manifest应用程序上强制使用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模块。 App的BuildConfig.DEBUG
可能是假的,但MyLib BuildConfig.DEBUG
可能是真的。因此,最好使用ApplicationInfo.FLAG_DEBUGGABLE
进行检查
我的经验是,BuildConfig.DEBUG
始终链接到gradle文件中的debuggable
构建属性。
buildTypes {
debug {
debuggable true
}
debug {
debuggable false
}
...
}
documentation也支持这个:
- boolean DEBUG - 如果构建是可调试的。
在gradle构建系统和Android Studio在2015年左右取代eclipse之前,getContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE
可能是确定构建是否可调试的唯一方法。
使用BuildConfig.DEBUG
因为它解析为一个常量,可以在编译期间使用该常量来优化代码。
一个确实突出了这些标志用法差异的领域是对我们的应用程序的笔测试。笔测试报告向我们指出,攻击者可以使用一种称为“挂钩”的技术,其中应用程序被重新编译,并将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()语句。