Performance Problems in Libraries and SDKs
It’s difficult to imagine modern android apps that don’t implement some external libraries or SDKs. After all, most apps have to leverage some combination of network image loading, crash tracking, advertisement, or analytics libraries and SDKs. It makes sense - developers shouldn’t have to reinvent the wheel (several wheels, actually) every time they want to create an application. However, it turns out that many libraries and SDKs cause major startup delays and other performance issues. These delays can be hard to track down because developers typically have little to no knowledge of the library or SDK’s implementation.
Common Performance Problems in Libraries and SDKs
There are a couple of common problems that we’re constantly telling developers to look out for. It turns out that some of these problems persist in libraries and SDKs, which means it’s all the more important to be vigilant when it comes to using and understanding third party code.
ClassLoader.getResourceAsStream is the most popular performance problem we see in libraries and SDKs. If a library or SDK is provided in JAR instead of AAR) format, ClassLoader.getResourceAsStream is the only way to load resources. Developers use JAR instead of AAR for a variety of reasons, the main one being that they want to distribute one package for both Java and Android.
Hung methods in the main thread are another common problem found in libraries and SDKs. Libraries and SDKs often need to be initialized, so it is convenient for their developers to provide an initialization method that does a lot of the heavy lifting. For instance, an advertisement SDK may acquire the list of installed apps to avoid showing you an ad for an app you’ve already installed. An A/B testing SDK may load feature toggles from a remote server. If the developers are not careful and do this heavy work in the main thread, your app will suffer.
Reflection is another common problem. Library and SDK developers often use reflection to make it easier for other developers to use their library or SDK. For instance, an app developer can create a REST client or a DAO object just by adding a few Java annotations. Unfortunately, when not used carefully, reflection can introduce huge overhead to any Android app.
Libraries and SDKs - Real-Word Examples With Top Apps
Performance problems are pervasive in libraries and SDKs. Here we describe the problems in the following 11 popular libraries and SDKs and the apps affected:
Tapjoy suffers from the ClassLoader.getResourceAsStream problem. Here’s an example (textPlus 5.9.9):
Other affected apps include Bible 5.11.3, Akinator FREE 4.04, AlarmMon 6.1.8, Yokee 2.0.205, Keek 5.0.6, SimSimi 188.8.131.52, InstaFisheye 2.6.8, Jaumo 3.5.3, My Diet Coach 4.2.8, Talking Angela 2.4, and ZombieBooth 4.32.
Startapp suffers from both hung methods in the main thread and ClassLoader.getResource problems. Here’s an example (Lovely Photo Frames 4.0.2):
Heyzap also struggles with properly managing the main thread. Here’s an example (from Mackolik 3.3.6) in which Heyzap makes 3 calls of packageManager.getInstalledPackages(), which takes ~236ms:
Yume, like many of the SDKs already mentioned, perpetuates the ClassLoader.getResource problem. Here’s an example (Talking James Squirrel 3.26.0):
Other affected apps include: Talking Babsy Baby: Baby Games 3.30.0
ClassLoader.getResource just wont stop cropping up. It shows up again in the Joda-Time library, as you can see here in this example (Yahoo Fantasy Sports 6.4.0):
Other affected apps include: TuneIn Radio - Radio & Music 13.6.1, My Pregnancy Today Tracker 1.17.1, LiveScore 2.1.4, Vevo - Watch HD Music Videos 2.1.8, Muslim Pro: Prayer Times Quran 7.0.6, and Timehop 3.1.1
Ormlite, too, suffers from calls to ClassLoader.getResource. In this example (from Anghami 1.8.58), the call takes nearly an entire second:
ActiveAndroid’s reflection usage is a concern, as it can cause some serious app slowdown, as seen here in Myntra 2.4.0:
Other affected apps include: Scribd - A World of Books 3.11
Jersey’s use of reflection is also pretty detrimental to app performance. It slows down Photobucket 3.3.6 (and a slew of other apps) significantly:
Yet again, ClassLoader.getResource finds its way into another SDK. AWS Android’s use of ClassLoader.getResource is exceptionally slow here in Moovit 184.108.40.206:
Unsurprisingly, SLF4J also suffers from ClassLoader.getResource:
What’s wrong with Logback? You guessed it - ClassLoader.getResource. See how it affects Audible 1.9.0 here:
Recommendation: Profile the libraries and SDKs you use to avoid surprises