Avid Android developers have longed faced a headache-inducing problem with their apps. The number of methods an app can have is limited. Well, it used to be limited. At long last, the good folks at Google provided a solution last October, but it was far from ideal. Though very easy to implement, the multidex solution complicated and prolonged compilation time significantly. Not standing still, starting with Lollipop (Android 5.0), the entire Android virtual machine was revolutionized to offer a much more endurable solution, the kind that even improves on the regular compilation time.

However, for the time being, the Lollipop solution isn’t ideal too. It requires developers to develop against Lollipop only, which could be problematic since most apps want to be compatible with wider ranges of audiences and might fear using features that aren’t available in earlier Android versions. So right now, the Lollipop solution is a good future-Android solution, but might not have much impact in the foreseeable present.

So what can be done in the meantime? We all agree that you shouldn’t give up on features and capabilities, just to avoid reaching the 65K limit. But there is no doubt that the best practice would still be to reduce your application method count.

So how can you still try to reduce your method count without losing that little spark that makes your app special?

A Short Overview: “Mama, Where are all these methods coming from?”

The method count limit stands roughly at 65K method (65,536 to be exact). That sounds like a huge number. If you’re a novice Android developer you might be thinking “how on earth can so many apps reach this number so quickly?” You’d probably be somewhat correct. It is not easy to write so many methods on your own. But app developers don’t write their entire app on their own.

App developers are using more and more third-party libraries (SDKs – Software Development Kits), which help them achieve certain goals and features that otherwise they’d have to develop completely on their own. From ads through GUI enhancements to social networks, crash reporting and many more, SDKs offer a wide range of capabilities and APIs that save precious development time and help get your app out there faster.

But each SDK adds to your method count, and some SDKs are even doing more than just what you bargained for. It’s not necessarily a bad thing, of course. However, the coup de grâce came from Google themselves. Their Google Play Services kit is a large SDK containing over 28,000 methods. With the limit being 65K, that number isn’t exactly low. And many app developers would like to use this SDK since it opens the door to the magical Google kingdom, a much desired capability that adds plenty of value to one’s app.

In this post, I won’t only explain how to selectively use the Google Play Services packages, but will also give you the lowdown on how many methods each one of these packages adds to your app. So hold on to your seats, it’s going to be a bumpy ride.

But First… Proguard and SafeDK

Before we start, let’s consider the whole picture. It’s not just SDKs that add to our method count. We often have plenty of legacy code that we might consider getting rid of, and there could be some SDKs that we’re not even using anymore and should simply remove from our app, no muss no fuss (and yes, technically, unused Google Play Services are considered exactly that).

The best practice before multidexing your app is to use Proguard. Now, some developers, when they hear the word Proguard, they automatically think of obfuscation, weird a.e.c.d-like packages and completely unreadable code and stack traces that are hard to debug should an error occur. I suppose that’s why many shy away from using Proguard altogether.

Well, fear not because Proguard is much more than just an obfuscation tool. In fact, you don’t have to use it for obfuscation at all. You can also use it for just minimizing your code. You can do so manually, or in Gradle, you can simply add the minifyEnabled flag:

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFile getDefaultProguardFile('proguard-android.txt')
        }
    }
}

In earlier version, that flag was called runProguard.

While obfuscation should only occur for release compilations, if Proguard helps you avoid exceeding the limit, you should consider running it with every build type and flavor, without obfuscation. Just beware that it might prolong your compilation as well, so you have to see which one is the lesser of two evils for you.

How to minify without obfuscate? As you can see, you need to supply Proguard with a set of rules. These rules mostly tell Proguard how to behave – not to remove certain classes, not to fail on others and so on. At the top of your rules file, simply add the line:

-dontobfuscate

And that’s it. Proguard will not obfuscate your code. Simple, right?

Note that using Proguard isn’t always smooth sailing. Sometimes Proguard might think that some class is not used and will remove it from your code, when in fact it is used (for example, via reflection). In that case, while running your app and trying to call that class you’ll get a weird NoClassDefFoundError. Don’t panic. Just add the class to your rules file with the keep flag and Proguard will not remove it:

-keep public com.example.myClass { *; }

This rule tells Proguard to keep the class and all its’ content (likewise, you can specify specifically which methods inside the class you don’t want Proguard to remove. You can also specify complete packages to keep intact and so on. Take a look at the documentation to learn more). With a few short trial and error iterations, your app can be easily minified with Proguard.

Proguard won’t necessarily remove SDKs that aren’t used. Moreover, it is not likely to remove entire libraries. Usually you would have to do this yourself in order to achieve the best result. You can identify your unused SDKs with the help of SafeDK’s ‘Apps X-Ray’ – this tool will automatically list the SDKs inside your app and will indicate which SDKs are unused. To get the Apps X-Ray trial version, all you need to do is send an email to contact@safedk.com.

And Now: The Google Play Services Playground

So how many methods does Google Play Services actually add? Well, as with everything in life, it’s much more complicated than just a bottom-line number. But let’s take it one step at a time.

The Google Play Services SDK actually contains 19 different SDKs. With Gradle, you can selectively choose which ones to use. All you have to do is add the following dependency to your app module’s build.gradle file:

dependencies {
   compile 'com.google.android.gms:play-services:7.5.0'
}

With 7.5.0 being the latest GPS version released at this time. It is labeled as revision 25 inside the Android SDK Manager.

In order to choose specific packages, replace the following line with as many dependency lines as you’d like, specifying specific packages. Say for instance, you just want Google Plus, Google Games, Google Ads and Google Maps:

dependencies {
   compile 'com.google.android.gms:play-services-plus:7.5.0'
   compile 'com.google.android.gms:play-services-games:7.5.0'
   compile 'com.google.android.gms:play-services-ads:7.5.0'
   compile 'com.google.android.gms:play-services-maps:7.5.0'
}

Not too difficult, but here’s the first catch. One of the glorious 19 SDKs is called play-services-base. If you include any Google Play Service package, it will automatically be added as well. How many methods does the base package contain? Nearly 8,000 (exact number below).

And here’s the second catch. I didn’t include just 3 packages in the example above. I didn’t even just include 4, if you count the base package as well. In fact, I included 5 packages. Why? Because the Google Games package uses the Google Drive package, and so that was imported as well (in reality, Google Ads also includes a package called tagmanager, but I’m only counting the “selectable” packages here).

So now we’re beginning to understand why it’s a little harder to count how many methods each package of the Google Play Services adds to our app. Including one package, does not necessarily mean excluding the others.

So here’s the lowdown – which packages you can add, how many methods they add and which other packages do they bring to crash the party. The data refers to the latest version of Google Play Services (7.5.0 / revision 25):

Package Method Count Added Packages Total Method Count Method Count with Base Package
play-services-base 7899 7899 7899
play-services-plus 1117 1117 9016
play-services-games 4036 play-services-drive 6302 14201
play-services-wallet 803 play-services-identity
play-services-maps
2822 10721
play-services-wearable 1355 1355 9254
play-services-location 1302 play-services-maps 3247 11146
play-services-nearby 505 505 8404
play-services-analytics 1798 1799 9698
play-services-drive 2266 2266 10165
play-services-fitness 1550 play-services-location
play-services-maps
4797 12696
play-services-ads 3707 3707 11606
play-services-safetynet 19 19 7918
play-services-identity 74 74 7973
play-services-maps 1945 1945 9844
play-services-panorama 9 9 7908
play-services-appindexing 186 186 8085
play-services-cast 954 954 8853
play-services-appinvite 26 26 7925
play-services-gcm 289 289 8188

Total number of methods: 28,175.

Some of these numbers, you have to admit, are truly atrocious. If all you wanted was the panorama package, you can’t just get nine methods, you have to get almost 8,000. No wonder so many apps are getting close or exceeding that 65K limit.

Some of these numbers may seem to be a bit inconsistent if you try to add them up. That’s because, again, the logic behind Google Play Services is a bit trickier than meets the eye. For instance, Google Analytics includes a single method from Google Ads in order to get the account’s Advertising ID.

Note that when computing how much each package adds to your app, be sure to exclude doubles (for instance, don’t count the base package more than once).

You Can’t Selectively Add Everything

And here’s the final sting. There are two tiny packages inside Google Play Services that cannot be selectively added.

The search package (giving you access to the Google Now API) includes only 22 methods. If you want to use it, you don’t have a choice but to add the entire 28,000+ methods, the entire Google Play Services. Hopefully, this will be fixed in the next version.

(Another “inaccessible” package is the appstate package that includes 111 methods, however it is now deprecated in favor of SavedGames, included in google-play-games package).

A Small Note to End With: Android Studio ≠ Gradle

It should be noted that while you must compile your Android Studio projects with Gradle, the other way around isn’t necessarily true. I am making the distinction between the two since you can certainly develop in a different IDE but still enjoy the capabilities Google only bestows upon Gradle by simply compiling your code via the command line with Gradle, for instance. It’s less convenient, sure, but I’m well aware of the fact that not everyone are so gun-ho to make the transition to Android Studio.

Summary

This is my third and final post dealing with Android’s mischievous 65K limit issue. In my previous posts, I’ve explored in depth the what, why and how to overcome. I’ve looked into the future and talked about multidexing with ART (introduced in Android Lollipop). And finally, in this post, I’ve spoken about the importance of Proguarding your app and of minimizing the SDKs that you use to what you actually need, both in terms of Google Play Services and in the SafeDK kick-ass `App X-Ray` tool, which I encourage you to try for free by emailing us at contact@safedk.com.