Google Play Services – on a much needed DIET

Later EDIT 2015 : Google now has split up the play-services library on modules (http://android-developers.blogspot.ro/2014/12/google-play-services-and-dex-method.html) so the below method is not needed anymore.

As you should know, Android has a DEX method count limit of 65 K. Adding multiple libraries & jars to your project, will easily break this limit. One such library is Google Play Services which is  a very large library. See this post from Jake Wharton : “Play Services is a Monolith Aboinmation” 

Google Play Services 5.0 which just launched contributes over twenty thousand methods to your app. 20k+. One third of the limit! Now that is scary.

This was written when Play Services 5.0 were released. Now with the release of PlayServices 6.1 and a ton of other SDKs added (FIT SDK, new Drive APIS, etc) that count definitely increased. So, your DEX limit exceeds 65K , what should you do now ?

1.Use ProGuard

It’s good to have proguard configured for your project. I really recommend to strip down, obfuscate and shrink your application… BUT at RELEASE time, not every time you deploy to a device. This would really slow down the development process, the build time will increase a lot, obfuscated stacktraces, etc, etc. There are also cases where you can’t use ProGuard on your project ( using Dagger, although it might be supported now) . So this is not really a viable solution for me… as a lot of people tend to say.

2.Use the new MultiDex Support

Since a few weeks, we can use the new MultiDexApplication as mentioned in this post . Quote from the author of this post :

Note: you should really, really Proguard before going down the Multidex rabbit hole.

No, thanks. I’ve tried it, not easily supported by Gradle yet, as it can be seen here : DEX’s 64K limit is not a problem anymore, well almost… , but it works. But this also increases my build time from 15 seconds, to 2 minutes + a lot of Android Studio OutOfMemory exceptions… Not an option. There are a lot of people commenting on forums and issues, as it can also be seen on Jake Wharton’s post about the Play-Services big method count problem, mentioning this is not a big problem , and that we should use ProGuard, quote from one of the comments :

 I’d hardly call Google Play Services an abomination just because a handful of seconds are added to everyone’s debug build flow. I’d suggest that the lack of a 1.0 release on Android Studio is a bigger problem in everyone’s workflow.

Are you joking ? Even adding only 30 seconds delay to the build, when we deploy a lot when developing on Android, this means : ~50 deploys/day * 30 seconds = 25 minutes ~25 times of the 50, I say you will get distracted while the build is in progress… = + 30-60 mins lost 1 man = 60-90 mins lost / day due to slow build times… 1 team of 3 people = ~4 hours lost / day = ~25-30 hours lost / week THIS IS A BIG PROBLEM.  None of the above are acceptable solutions.

3.Google Play Services REPACKAGED

So, I re-packaged google play services to strip down it’s size. Here’s how to do it : 1.Go to ANDROID_HOME\extras\google\m2repository\com\google\android\gms\play-services\6.1.11 and get the play-services-6.1.11.aar file from there 2.Un-zip it ( I used WinRar ) and obtain the classes.jar file from it. This is where all the play services code is packaged. 3.Get JarJar – a utility that makes it easy to repackage Java libraries and embed them into your own distribution. 4.Create a services.rules file for jarjar. I use only Maps and Google Cloud Messaging in my application, so my services.rules file contained :

 keep com.google.android.gms.gcm.*
 keep com.google.android.gms.maps.*
 keep com.google.android.gms.location.*

5.Now, copy jarjar.jar , classes.jar , services.rules in the same folder and run :

java -jar jarjar.jar process services.rules classes.jar classes-stripped.jar

You’ll see classes-stripped.jar will be much smaller than the previous classes.jar. Rename classes-stripped.jar to classes.jar and add it back to the play-services.aar using an archive editor ( I used WinRar). 6.In Android Studio, use File->Import Module -> Import .JAR or .AAR package , and point to the .aar file that we just edited. That’s it. Now you have google-play-services added to your app as an android project and you’ll keep your quick build time. Did not had any troubles so far.. So this is the only viable solution for me right now. In the future, I really hope the folks at Google take the suggested approach by a lot of developers out there, and unbundle the play-services. Looking forward for the day when we will be able to add in build.gradle  just :

 compile 'com.google.android.play-services:common:6+'
 compile 'com.google.android.play-services:maps:6+'

Even more, looking forward for the day when DEX count will be removed.

About Ovidiu

Passionate Android Developer. What else? Snowboarding. Football. Stuff like that.
This entry was posted in Android, Google and tagged , , , , , , , , . Bookmark the permalink.

3 Responses to Google Play Services – on a much needed DIET

  1. tomurka says:

    Excellent article! You have saved my day!

  2. Allen says:

    Very nice! I’ve tried to solve this problem for many days. Multidex gave me hope but still fail to solve the problem.
    The only question now is that, in Manifest file, I have this error: android:value=”@integer/google_play_services_version”.
    Would you please help me solve it? Or I can just omit this line?
    Thank you!

  3. Thomas says:

    For those who found this through a search engine: it’s worth noting that this technique is outdated. Nowadays, you don’t need to compile the full Google Play Services library into your application; you can pick and choose the (sub)libraries that you need: http://developer.android.com/google/play-services/setup.html

Leave a reply to Allen Cancel reply