After looking around at a few Android applications, I realised that there are many developers who don’t know about a great tool in Android Studio — the Android APK Analyzer. I cringe when I go to download a basic application (most of these apps are really simple) and the download size is over 40MB. Whenever I see this, if I have a bit of time, I like to dive into looking at what is bloating the APK.
Looking into these different APKs, I’ve come across some interesting files, from test data to iOS image files, I’ve seen it all. Whilst analyzing these APK files, I’ve noticed some common trends/mistakes that developers make.
I took a look at some of the Top(*) South African Android apps from the Google Play Store and found some interesting information. This blog post aims to show you how easy it is to look into your app and see what the biggest culprit of eating data in your app is. [Disclaimer: I’m not displaying which apps did what — you can figure that out yourself (reach me on Twitter if you want me to help you lower your APK size). ]
The average download size of the Top(*) South African Android app is ~15.3MB — with the largest size sitting at ~ 42MB.
The largest app on the store had 18.8MB of images and 14MB of native libraries packaged inside.
Okay, so I’ve hopefully gotten your attention. We know our apps are too big, but how do we go about finding this information and improving our apps?
Android APK Analyzer
The APK Analyzer is a tool, built-in to Android Studio, that allows you to inspect an APK and see what makes up the contents of an APK file.
To use it, you can either drag an APK file into Android Studio and the Analysis will start, or you can just head to the “Build” menu and select “Analyze APK” from the menu.
Once you have opened the APK file, you will see detailed information about the APK. The tool contains information such as how big the certain folders are and the percentage of the Download size that the folder takes up.
There are a few common scenarios that seem to have plagued some of the top Android APKs. Let’s discuss three things you should look into implementing in order to reduce the size of your APK file.
3 Most Common Issues in Large APKs:
The most common issue I have seen whilst analyzing different APK files, the images not optimized. In the one example above 18MB/42MB of the APK is just images. 😱
The average amount of space that images use in these top apps is over 44% of the download size.
One app that I examined, had a 3.7MB image that is used for the Splash Screen. Now not only is that image huge, but this image is placed inside all the different drawable folders (of varying sizes), which means the total size of including this one image is 14.9MB. This image is displayed for a few seconds on the launch of the app. This was not the only app with this issue.
Another app that I examined, had included possibly every single image of their different products that they sold inside their app. This took up 80% of the size of their application. 😱
Here are some tips for reducing your image sizes/usages:
- Don’t package images that aren’t important to every single user of the application. For instance, this app in question above had about 20 different images that related to different products that I’m 100% sure most of the users won’t ever see. Store images on a server — compress them, and download and cache them when they are required. (Also — only download the size that you need. Take a look at something like Cloudinary for image resizing and hosting.)
- Compress all your images! Please, for the sake of my sanity (and your user’s data), compress that 8MB background image. For instance, use a JPG instead of a PNG, use WEBP instead of JPG if possible. Compress it, a lot!
- Don’t repeat the image in different folders if it is a large image — look at using either the highest dpi folder or look into -nodpi or -anydpi and place the image only once in that folder (then load the image using an Image Loader like Glide to make sure it can handle the size in the view). Read more about -nodpi and -anydpi here.
- Use VectorDrawables (SVGs) instead of PNGs where possible (for all icons etc). VectorDrawables are supported from Android API level 7+.
Developers love using libraries — hey so do I! But let us have a quick chat about using libraries. Before deciding to bring a library into your project, you should look into how big the library is and what it needs to include in order to run.
A few apps that I looked into have their libs folder, filled with libraries for different flavour devices — for example, they are including all the different device architecture flavours of librealm-jni.so. That’s 5MB of data I’ll never get back.
If you really need to include a native library — then please, please, please make sure you are using APK splits or use NDK filters. This allows you to release multiple different versions of your app to users that have different architecture device (ie x86 or armv7) so that users don’t have to download a whole bunch of libraries they will never need. You can also do APK splits on the different density devices, but maintaining different versions of your app can get quite tricky. (Side note — have you heard of Room from the Android Architecture Components?)
Use APK Splits or NDK filters when packaging native libraries with your Android apps
Another common trend I observed is that a lot of developers are including fonts in their assets folder.
Did you know that in Android API 26 (Oreo) and Support Library 26, Downloadable Fonts were introduced?
This means you no longer need to package a font with your application, and a user will only have to download a font once, and it’ll be reused in different applications. Read more about Downloadable Fonts here.
Use Downloadable Fonts instead of packaging fonts inside your APK file
Test Data — A few apps have files in them that look like test data. Remove those from your final APK file, your users don’t need them.
ProGuard — A lot of APKs don’t use ProGuard. Now you might think that you don’t need it because you don’t mind if people read your code, but ProGuard is more than just an obfuscation tool, it also minifies your code and can remove unused classes and files. Go enable it! (*just double and triple check everything works afterwards 😬)
Xamarin — How can you tell when an app is written in Xamarin? A lot of .dll files and the libmonosgen-2.0.so files. Did you know, a basic Hello World Xamarin app is 8.2MB? If you are using Xamarin for mobile development, I strongly suggest you think about the effect on the size of your overall app.
There are many great apps on the Google Play store that can be improved with just these few simple suggestions. It is crazy to think that so many users are subjected to downloading large images over and over again.
Please, for the sake of my data bill and others, please reduce the size of your APK (or at least reduce the size of your images).
Reach me on Twitter if you have any thoughts or questions.
Stats from Top(*) South African Android Apps:
- Average download size: 15.22MB
- Average lib folder size: 3.79MB
*Disclaimer: The top apps I looked at are only an estimate of the top and may not be the real top — ie I looked through *my* top 300 on Google Play, and choose a few, no real science here. (The top may be different for me vs you, based on Google’s fancy algorithms)