Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I enable language-level assertions on the Android Runtime (ART)?

I have a Pixel-C that I am developing for. My minimum API level is 21, which is also the level at which ART replaced Dalvik. I have tried both of:

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

And they seem to execute successfully. I have placed

assert false : "assertions are active!";

in my onStart, and I am not seeing any stack traces in logcat. I would expect the app to exit immediately after I install and run it. Please tell me how to get this assertion to execute.

Please do not mention JUnit or other ways to do assertions, nor any solution that requires explicitly throwing an Error. Production code should never throw Errors, nor attempt to catch and handle them. That's why assertions were added to the language, to have a way to cause the app to crash when invariants are violated in test environments without incurring any overhead or risk whatsoever in production.

This 6-year old question is basically the same, but for Dalvik (IE out of date) and the solutions are either not working or not good: Can I use assert on Android devices?

like image 208
Travis Well Avatar asked Mar 14 '16 20:03

Travis Well


People also ask

What happened to art and libcore in Android 11?

The Android Runtime (ART) and managed core library (libcore) were part of the Runtime module effort in Android 10 along with the native runtime (Bionic) and ICU. In Android 11, ART and libcore are packaged as non-updateable APEX. Bionic and ICU (code and data) remain on the platform and are separated from ART to improve updatability.

What is the Android Runtime (ART)?

The Android runtime (ART) is the default runtime for devices running Android 5.0 (API level 21) and higher. This runtime offers a number of features that improve performance and smoothness of the Android platform and apps. You can find more information about ART's new features in Introducing ART .

Why don't Android apps support more languages?

Browser apps can avoid offering to translate pages in a language the user already knows, and keyboard apps can auto-enable all appropriate layouts. Up through Android 6.0 (API level 23), Android supported only one or two locales for many common languages (en, es, ar, fr, ru).

Can I change the language of an Android app at runtime?

Changing the language on Android at runtime was never officially encouraged or documented. The resource framework automatically selects the resources that best match the device. Such behavior is enough for common applications, so just make sure you have strict reasons to change it before proceeding further.


2 Answers

I reluctantly submit that the answer seems to be: you can't enable assertions on ART. What works is to replace all assertions with an explicitly thrown AssertionError wrapped in an if statement like this:

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

Apparently, in API levels 21, 22, and 23, ART will actually completely remove the bytecode for this if block from non-debug builds upon install, ie where BuildConfig.DEBUG == false. At these API levels, ART compiles bytecode to native on install, but that is changing for Android N. So I infer that on Android N, ART may still see the negligible performance penalty in production of checking BuildConfig.DEBUG until the optimizer potentially compiles it out after a certain amount of usage has occurred.

I don't like this because it removes the ability to choose to run assertions for a specific package in an apk. The choice now is at the granularity of the whole build, and only at build time.

The other major reason this sucks is that it's verbose and ugly. The brevity of assertions makes them good for documenting your code inline. Although these hacked-up assertions can serve as documentation, they're no longer unimposing and legible. Look at that example. That should be one line, not five.

If you have an idea why ART doesn't seem to support assertions, for example, inside knowledge about technical hurdles or Google's internal politics, please comment or leave a new answer. My assumption is that the widespread misunderstanding of the usefulness and role of assertions, and the prevalence of antipattern usage has led the Android team to just disable the feature rather than educate everybody. Maybe the Android team suffers from the same misunderstandings.

like image 99
Travis Well Avatar answered Sep 26 '22 15:09

Travis Well


Android Gradle Plugin / Android Studio as of version 4.1 enables Java asserts in debug builds automatically.

like image 31
laalto Avatar answered Sep 22 '22 15:09

laalto