morristech
4/30/2018 - 9:24 PM

Faster way to include stripped down Google Mobile Services in your application as a workaround to the 64k dex method limit problem that GMS

Faster way to include stripped down Google Mobile Services in your application as a workaround to the 64k dex method limit problem that GMS frequently introduces. See README.md for details.

Context

I was previously using https://gist.github.com/dmarcato/d7c91b94214acd936e42 to strip down Google Mobiele Services, but the build times for my project in Android Studio consistently exceeded 75 seconds; this solution is much less dynamic (and even a little ugly) but keeps my build times less than 15s.

Assumptions

  • Your app module has a directory named aars that will work as a project specific Maven repository; this directory should be placed under version control.
  • Maven (mvn) is installed and available on your path when running this script.

Usage

See what versions of Google Play Services are installed

  • cd $ANDROID_HOME
  • cd extras/google/m2repository/com/google/android/gms/play-services/
  • ls will show you what versions are installed (ex: 6.1.11)

Building the stripped AAR

  • Go to your app module
  • Place the Python script below next to build.gradle (for the app module, not the project module)
  • Make sure the Python script is executable (chmod +x stripPlayServices.py)
  • Run something like ./stripPlayServices 6.1.11

Disclaimer

I make absolutely NO claim the Python script follows typical Python code style, is clean, or is even safe. It is just a dumb, brute force script.

Testimonials

  • "looking good.... down to 1 sec build time as opposed to 17 sec!"
repositories {
    maven { url 'aars' }
}

dependencies {
    compile 'com.google.android.gms:play-services-stripped:5.0.89'
}
#!/usr/bin/python

# Usage: stripPlaySerices.py [GMS version]
# Example: ./stripPlayServices.py 5.0.89

import os
import shutil
import sys
import zipfile

# GMS packages to remove.
strippedPackages = [
    "com/google/ads",
    "com/google/android/gms/actions",
    "com/google/android/gms/appindexing",
    "com/google/android/gms/cast",
    "com/google/android/gms/drive",
    "com/google/android/gms/games",
    "com/google/android/gms/location",
    "com/google/android/gms/maps",
    "com/google/android/gms/panorama",
    "com/google/android/gms/plus",
    "com/google/android/gms/wallet",
    "com/google/android/gms/wearable"
]

# File info
gmsVersion = sys.argv[1]
repoPath = os.environ["ANDROID_HOME"] + os.sep + "extras" + os.sep + "google" + os.sep + "m2repository" + os.sep
gmsRepoPath = repoPath + "com" + os.sep + "google" + os.sep + "android" + os.sep + "gms" + os.sep + "play-services" + os.sep + gmsVersion + os.sep
gmsFileName = "play-services-" + gmsVersion + ".aar"
gmsStrippedName = os.path.splitext(gmsFileName)[0] + "-stripped.aar"
gmsTempDir = gmsFileName + ".tmp" + os.sep
classesName = "classes.jar"
classesFileName = gmsTempDir + classesName
classesTempDir = classesFileName + ".tmp" + os.sep

# Clean up any previous work
shutil.rmtree(gmsTempDir, ignore_errors=True)

# Extract the AAR in the ANDROID_HOME Maven repo.
gmsOriginal = zipfile.ZipFile(gmsRepoPath + gmsFileName, "r")
gmsOriginal.extractall(gmsTempDir)
gmsOriginal.close()

# Extract classes.jar
classesOriginal = zipfile.ZipFile(classesFileName, "r")
classesOriginal.extractall(classesTempDir)
classesOriginal.close()
os.remove(classesFileName)

# Remove what we don't care about
for packageName in strippedPackages:
    shutil.rmtree(classesTempDir + packageName)

# Recreate classes.jar
shutil.make_archive(classesFileName, format="zip", root_dir=classesTempDir)
shutil.rmtree(classesTempDir)
os.rename(classesFileName + ".zip", classesFileName)

# Recreate the AAR
shutil.make_archive(gmsFileName, format="zip", root_dir=gmsTempDir)
shutil.rmtree(gmsTempDir)
os.rename(gmsFileName + ".zip", gmsStrippedName)

# Intstall the AAR to our hack Maven repository
mvnInstallCmd = "mvn install:install-file -Dfile=" + gmsStrippedName + " -DgroupId=com.google.android.gms -DartifactId=play-services-stripped -Dversion=" + gmsVersion + " -Dpackaging=aar -DgeneratePom=true -DgenerateChecksum=true -DlocalRepositoryPath=aars"
os.system(mvnInstallCmd)

# Clean after ourselves
os.remove(gmsStrippedName)