Matt’s Tidbits #2 — Sometimes there’s a bug in the tool

Matthew Groves
3 min readFeb 5, 2019

--

My first tidbit talked about a SharedPreferences pitfall. This time, we’ll look at a case where there was a bug in the IDE, and what you can do about this!

Back in 2017 (and the days of Android Studio 2.3), I encountered a bug where my app would crash on certain devices:

java.lang.NoSuchMethodError: No interface method getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; in class Ljava/util/Map; or its super classes (declaration of 'java.util.Map' appears in /system/framework/core-libart.jar)

This came from the following code:

Why was this happening? On some devices this returned the expected value, "bar", but on others it would crash. The answer to this was found in the documentation for the getOrDefault() method:

The “added in API level 24” is the key statement here. Java is a constantly evolving language, and so not all features are available on every device. Wouldn’t it be nice if Android Studio warned us about this sort of thing?

The good news is, it does. The bad news is, sometimes there are bugs that cause these features to stop working:

https://issuetracker.google.com/issues/37137282

The major breakthrough for me was learning that there was a way to report bugs in Android Studio:

In my case, this bug had already been reported (you can search for open bugs at https://issuetracker.google.com), but it’s important to know that you can file bugs against the tools and that JetBrains will do their best to address them. Also, if a particular issue is affecting you, take a moment to “Star” the issue — this helps JetBrains have an idea of how many people are affected by the bug.

Coming back to the problem at hand though (the app crashing after calling this sometimes non-existent method), how do we solve this?
A few options are:

  • Increase your app’s minSdk to at least 24 so you’re guaranteed this method will exist (less desirable, since then you’ll potentially be preventing a large number of users from running your app)
  • Add a @RequiresApi annotation to the method using this code (which will cause Android Studio to warn you if you try to run it on older devices, but just defers where you solve the problem since you can’t call the containing method now)
  • Don’t use this method at all (great, what am I supposed to do now?)
  • Write your own helper method (this may be difficult to maintain or contain unintended bugs though)

If you’re feeling a little stuck, I’d like to propose an alternative solution that’s especially nice in Kotlin:

This only works if you’re storing non-null values in your map, but it is a nice alternative that is supported on all versions of Android!

If you do need to support null values, then you’ll need to write your own code — I would suggest creating an extension function such as this:

One more thing…

Earlier in the article, I mentioned how raising your app’s minSdk version may prevent a large number of users from using your app — if you want to see what this number is, you should check out Google’s Android Developer dashboard.

This information is unfortunately only listed for all devices across the globe, so it may not be strictly applicable to the region(s) your app is targeting, but you can also see the specific OS version breakdown for your own app in the Google Play Console.

Oh, and if you’re still using Android Studio 2.3, you should upgrade to at least 2.4 (which fixes this bug), if not the latest version — the tools are constantly improving, and you should check them out!

Have a suggestion or alternative solution you’d like to propose? Leave a comment below! Also, please follow me on Medium if you’re interested in being notified of future tidbits.

This tidbit was originally delivered on 8/18/2017.

--

--

Matthew Groves

Digital Products NE Mobile Capability Co-Lead & Senior Software Engineer in Boston, MA — https://www.linkedin.com/in/matthew-groves-85677631/