How to whitelist StrictMode violations on Android based on stacktrace
android.os.StrictMode) is an amazing tool that should be used by any Android developer that cares about quality and performance of their app. There are plenty resources available online that discuss the benefits of StrictMode and how you can get started. I will leave this discussion out of scope of this post, so you can take my word that
StrictMode is too awesome to ignore.
However, one of the unfortunate disadvantages of
StrictMode is that up until Android P (which added
penaltyListener) once you implement
StrictMode, it’s applied as a blanket policy for your entire app. As a result, all violations, even in 3rd party libraries, are reported and enforced so it’s almost impossible to use
penaltyDeath as your primary violation handling policy.
There are some hacks you can apply for selective code suppression as discussed here. However, this approach only works well if you have a small number of callsites that you need to whitelist, so it’s most useful for handling non-blocking
StrictMode violations during app start up.
Things become more complicated if you want to whitelist only certain
StrictMode violations based on the stack trace. For instance, on Samsung devices that use SnapDragon chips, you will notice the following
DiskRead violation related performance optimizations by
Whitelisting disk reads for every
dispatchTouchEvent call in all of your activity is probably NOT something we’d like to do. Ideally, we’d simply whitelist all violations that are caused by the initialization of the
As I mentioned above, Android P added the ability to set a
penaltyListener for your
StrictMode policy. You can use this listener to watch for all violations and crash the app for all non whitelisted ones. On Android N and above, you can accomplish similar results via some Java reflection hackery. Typically, I always vote against reflection hacks, but this one in particular is actually used by Google as Kurt Nelson describes in his talk on
StrictMode at AtScale Conference.
To save you the time, the code is below. You can watch Kurt’s video for the details, but the basic idea is to use a custom
ArrayList in the static private field of
violationsBeingTimed. All new violations will go through the
add method of the ArrayList. If the call to
super.add is omitted, the violations are skipped.