java - 如何在 Android 运行时 (ART) 上启用语言级断言?

标签 java android testing assertions android-runtime

我有一台 Pixel-C,我正在为其开发。我的最低 API 级别是 21,这也是 ART 取代 Dalvik 的级别。两种我都试过了:

adb shell setprop dalvik.vm.enableassertions all
adb shell setprop debug.assert 1

而且它们似乎执行成功。我已经放置了

assert false : "assertions are active!";

在我的 onStart 中,我没有在 logcat 中看到任何堆栈跟踪。我希望应用程序在我安装并运行后立即退出。请告诉我如何执行此断言。

请不要提及 JUnit 或其他断言方式,也不要提及任何需要显式抛出错误的解决方案。生产代码不应该抛出错误,也不应该 try catch 和处理它们。这就是为什么将断言添加到语言中的原因,以便在测试环境中违反不变量时有一种方法导致应用程序崩溃,而不会在生产中产生任何开销或风险。

这个 6 年前的问题基本上是一样的,但是对于 Dalvik(IE 已过时),解决方案要么不起作用要么不好: Can I use assert on Android devices?

最佳答案

我不情愿地认为答案似乎是:您不能在 ART 上启用断言。有效的方法是用包裹在 if 语句中的显式抛出的 AssertionError 替换所有断言,如下所示:

if (BuildConfig.DEBUG) {
  if (writeBuffer.hasRemaining()) {
    // As with all assertions, this condition should never be met.
    throw new AssertionError("whole buffer not written");
  }
}

显然,在 API 级别 21、22 和 23 中,如果在安装时从非调试构建 block (即 BuildConfig.DEBUG == false),ART 实际上将完全删除字节码。在这些 API 级别,ART 在安装时将字节码编译为 native ,但 Android N 正在发生变化。因此我推断,在 Android N 上,ART 在检查 BuildConfig.DEBUG 的生产过程中可能仍然会看到可忽略不计的性能损失,直到优化器可能对其进行编译在发生一定数量的使用后退出。

我不喜欢这个,因为它删除了选择为 apk 中的特定包运行断言的能力。现在的选择是在整个构建的粒度上,而且只在构建时。

这很糟糕的另一个主要原因是它冗长且丑陋。断言的简洁性使其非常适合内联记录代码。尽管这些乱七八糟的断言可以作为文档,但它们不再威严和清晰。看看那个例子。那应该是一行,而不是五行。

如果您知道为什么 ART 似乎不支持断言,例如关于技术障碍或 Google 内部政治​​的内部知识,请发表评论或留下新答案。我的假设是,对断言的用途和作用的广泛误解,以及反模式使用的盛行,导致 Android 团队只是禁用该功能,而不是对每个人进行教育。也许 Android 团队也有同样的问题 misunderstandings .

关于java - 如何在 Android 运行时 (ART) 上启用语言级断言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35997703/

相关文章:

css - Safari 5 与 Safari 4 : Are there any compatibility differences?

java - 装饰一个继承 protected 可观察对象的类

java - Azure 移动服务 Android 错误

java - 无法从子类中通过 `super` 访问静态字段?

android - 分享 Intent 在 android marshmallow 中不起作用

java - 在附加页面上使用倒计时器

java - 如何在 android 中通过清理处理全局状态

java - 通过反射检索参数值

testing - 在 Selenium 中断言和验证

android - 如何在 Espresso 中选择 ListView ?