On Android and DEX

Developing Android apps has become easier and easier thoughout the years, in particular as more developers jumped onboard and started crafting libraries for the community. Everything, from asynchronously loading images to parsing JSON, is now more straightforward than ever, thanks to the likes of Picasso, Gson and thousands more. And let's not forget about supporting older Android versions, too! Google provides us "support libraries" that we use, for instance, to bring Material Design goodness to everything that came before Lollipop. It's all a matter of adding a 'compile' statement to our Gradle build file and we are good to go. Thanks, progress!

However, as you may or may not are (though you should be) aware, there is a limit to the methods that your app can reference, and that limit amounts to 65536. More specifically, this limit is found inside the header of the DEX file, which contains all the compiled Java classes required by our app. It may seem like a lot of room for one app, but if you start considering that the most popular libraries contain thousands of methods each, that limit will look tremendously nearer to you.

This issue has grown bigger and bigger, and big companies were usually the first to trip into this obstacle, having to resort to hacky workarounds (e.g. loading a secondary DEX at runtime, or using ProGuard/DexGuard to strip the libraries from unused methods). But there was no official way of addressing the problem, especially from Google. Until Lollipop, of course. Enter MultiDex.


MultiDex to the rescue!

Starting from Lollipop, we have a new runtime called ART (Android RunTime). Among the greatest advantages that it brought, we find the ability of loading multiple DEX files for a single app. By explicitely declaring the use of MultiDex programmatically, the build system takes care of creating multiple DEXs and bundling them into the final APK. Thanks to ART, the DEXs are then assembled back and converted to another file (an OAT file), which will then be loaded when the user opens the app.

But what about Android versions prior to Lollipop? Since they still run on the Dalvik runtime, a different approach had to be taken. In this case, DEXs are loaded at runtime by patching the class loader. However, this technique is a little "hacky", and thus is not guaranteed to work across all the previous Android versions. For this reasons, big companies are still likely to rely on their custom-made solutions.

Even though MultiDex offers a way out, the recommended approach is still the following:

Stay below the limit, as much as you can.

Staying below the limit (or, what this is all about)

This service should help you dealing with the issue of the methods limit. By checking how many methods a library contains, you can determine whether it fits in your app, before drowing into the dreadful experience of not being able to build anymore. In addition, you are able to check what dependencies does the library rely on, and how many methods do they contain as well.

DISCLAIMER

The methods count is read directly from the DEX header file and is meant to be an UPPER BOUND to what will end up in the final APK. Be aware that there are techniques, such as ProGuard's stripping, that can reduce the overall methods number and library size (drastically, in some cases).


Which libraries are supported?

Every Android/Java library that you can find the Gradle 'compile' statement for. However, these are the repositories that are currently included in the process:

  • Maven Central
  • jCenter
  • JitPack

Know another one that we should add? Be sure to let us know!


Why so serious slow?

Because the library you have requested has not been computed yet. The computation of a library involves fetching the library, DEXing it and retrieving the method number and the size. For large libraries, this can take quite a long time (even minutes). However, the more libraries are added to the system, the less chances are that you will ask for a library that has not been processed yet.


How do I know the current count for my APK?

There are a few options. APK method count allows you to inspect an APK from your local machine (the APK is never uploaded to the website, it is computed locally). The same goes for dex-method-counts, a script that quickly displays the APK dependencies, broken down by package.


What's next?

This is the initial version of the service, and is therefore barely functional. First of all, we will try to make it as stable and responsive as possible. A thing that we have planned for the near future is adding a chart for each library, that shows the trend on the methods count and the size. We believe it's going to be extremely interesting, and it will perhaps instill some awareness to developers that recklessly include huge libraries without seeking for alternatives first.

Roughly, this is what the current roadmap looks like:

  • Stability and reliability
  • Comparisons
  • Process multiple entries at once
  • Charts

Can I help?

Sure! We are extremely open to suggestions and improvements. Be sure to contact us via the social channels that you find at the bottom of this page. And in the meantime, thank you! :-)


Credits

We really need to thank some people, who helped me building this service and gave their invaluable opinion on several matters. Our respect goes to you.