Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Gradle task to strip unused packages on Google Play Services library
def toCamelCase(String string) {
String result = ""
string.findAll("[^\\W]+") { String word ->
result += word.capitalize()
}
return result
}
afterEvaluate { project ->
Configuration runtimeConfiguration = project.configurations.getByName('compile')
ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult
// Forces resolve of configuration
ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion
String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library"
File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir
Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") {
inputs.files new File(playServiceRootFolder, "classes.jar")
outputs.dir playServiceRootFolder
description 'Strip useless packages from Google Play Services library to avoid reaching dex limit'
doLast {
copy {
from(file(new File(playServiceRootFolder, "classes.jar")))
into(file(playServiceRootFolder))
rename { fileName ->
fileName = "classes_orig.jar"
}
}
tasks.create(name: "stripPlayServices" + module.version, type: Jar) {
destinationDir = playServiceRootFolder
archiveName = "classes.jar"
from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) {
exclude "com/google/ads/**"
exclude "com/google/android/gms/analytics/**"
exclude "com/google/android/gms/games/**"
exclude "com/google/android/gms/plus/**"
exclude "com/google/android/gms/drive/**"
exclude "com/google/android/gms/ads/**"
}
}.execute()
delete file(new File(playServiceRootFolder, "classes_orig.jar"))
}
}
project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task ->
task.dependsOn stripPlayServices
}
}
@PaNaVTEC

This comment has been minimized.

Copy link

commented Jul 11, 2014

I just added:

exclude "com/google/ads/**"
exclude "com/google/android/gms/analytics/**"
exclude "com/google/android/gms/games/**"
exclude "com/google/android/gms/maps/**"
exclude "com/google/android/gms/panorama/**"
exclude "com/google/android/gms/plus/**"
exclude "com/google/android/gms/drive/**"
exclude "com/google/android/gms/ads/**"
exclude "com/google/android/gms/wallet/**"
exclude "com/google/android/gms/wearable/**"

for 5.0.77 version

@basantmatharu

This comment has been minimized.

Copy link

commented Jul 13, 2014

How do you include this file on a project?

@adelnizamutdinov

This comment has been minimized.

Copy link

commented Jul 13, 2014

just paste it to the bottom of your app's build.gradle file

@alorma

This comment has been minimized.

Copy link

commented Jul 14, 2014

What happen if i use some ef those package? Games, analytics...?

@PaNaVTEC

This comment has been minimized.

Copy link

commented Jul 14, 2014

@alorma then you have to remove the lines that you use, so if you use games, do not include in your build.gradle:

exclude "com/google/android/gms/games/**"

And you're ready :)

@megatronxxx

This comment has been minimized.

Copy link

commented Jul 14, 2014

I'm using latest version of the plugin and it has different folders structure. So this task doesn't work. Also android.applicationVariants.each seems to be obsolete as well.

@BetweenTwoBits

This comment has been minimized.

Copy link

commented Jul 15, 2014

I'm having trouble getting this to work on AS 0.8.2, gradle plugin 0.12.0 any advice?

@BetweenTwoBits

This comment has been minimized.

Copy link

commented Jul 15, 2014

nevermind, ended up getting it working by getting rid of what ended up being a second android declaration that was causing a conflict.

@VerachadW

This comment has been minimized.

Copy link

commented Jul 17, 2014

I'm having a strange problem that stripPlayServices is not called by running from configuration in AS 0.8.2, but it work fine with ./gradlew assembleDebug. Anyone have an idea?

@dmarcato

This comment has been minimized.

Copy link
Owner Author

commented Jul 18, 2014

I've updated the script to be compatible with all 0.12.x versions of the Android Gradle Build Tools, should work fine now.
I'm also stripping only the version that is declared in the dependencies section.

@robbypond

This comment has been minimized.

Copy link

commented Jul 20, 2014

Awesome. In one project I include play services only with a specific product flavor. How would I modify the script to only run when this flavor is building? The problem I'm having is that

resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion

does not find the play-services module since it is not included in the default configuration dependencies.

@dmarcato

This comment has been minimized.

Copy link
Owner Author

commented Jul 22, 2014

@robbypond you should change compile in the following line with the configuration name where you require Play Services:

    Configuration runtimeConfiguration = project.configurations.getByName('compile')

Also, you may wanna change the part where you trigger the task to be executed only with one particular flavor, to do so you should change this:

    project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task ->

with something like this

    project.tasks.findAll { it.name.equals('prepareMyFlavorDependencies') }.each { Task task ->
@suarezjulian

This comment has been minimized.

Copy link

commented Jul 23, 2014

I can't get this to work, I've been trying to solve the issue myself but I need help. My situation is as follows: I have a main project and a library project, the library project has the dependency on play services which then the main project inherits, I've put the script above on the build.gradle files for both projects, but I still get the mehtod count error. I tried doing some debugging and I found out that the issue is that the classes.jar file doesn't exist when the stripPlayServices task is executed and that's why this is failing for me. I tried running the task manually (:myproject:stripPlayServices) after gradlew.bat assemble and it works correctly in this case (I can see the classes_orig.jar being generated and the original file decreases size).

I'm using windows AS 0.8.3, gradle 1.12 and android gradle plugin 0.12

@suarezjulian

This comment has been minimized.

Copy link

commented Jul 24, 2014

In case anyone has the same problem as I stated above, the cause of this was that I had set org.gradle.parallel=true on my gradle.properties file, and this causes the stripPlayServices task to be executed too early on the build process. My workaround (sadly) was to disable parallel mode which greatly speeds up builds. Anyway great work @dmarcato I hope someone with more gradle skills finds a way to make this work even when enabling parallel builds.

@cypressious

This comment has been minimized.

Copy link

commented Jul 25, 2014

Could someone create a gradle plugin from this code? Optimaly you would define the packages you need as parameters.

@VinyWenkz

This comment has been minimized.

Copy link

commented Jul 25, 2014

Hello.. I need help pls.. I can't make this work. I don't have this kind of configuration org.gradle.parallel=true . The stripPlayServices is getting called but the number of method references is still the same. Thanks

@Takhion

This comment has been minimized.

Copy link

commented Jul 27, 2014

I'm getting this error:

Converting class java.lang.Boolean to File using toString() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use java.io.File, java.lang.String, java.net.URL, or java.net.URI instead.
@VinyWenkz

This comment has been minimized.

Copy link

commented Jul 28, 2014

Hi.. sorry, actually, it worked. However, the dex method count is still the same. That's odd, isn't it?

@vishyrich

This comment has been minimized.

Copy link

commented Jul 29, 2014

works like a charm! thank you so much for this!!

@dannyroa

This comment has been minimized.

Copy link

commented Aug 15, 2014

How do you import ResolutionResult, ModuleVersionIdentifier, etc inside build.gradle?

@ZacSweers

This comment has been minimized.

Copy link

commented Aug 21, 2014

Has anyone found a way to do this without causing gradle to recompile again? The changes to classes.jar get recognized internally as cause to recompile the whole project between builds, even if nothing has changed. This essentially forces the build time to be close to about the time it takes to build after a clean, in our case from 10s up to 45-50s. This is an elegant way to handle it, but for the moment the tradeoff is too great.

Some alternative approaches we've tried:

  • Not deleting the classes_orig.jar file, and checking to see that exists when checking if upToDateWhen, but it appears that every run re-explodes the AAR files over it (AKA the whole directory is replaced every run, and artifacts can't be left for later checking).
  • Forcing the stripPlayServices task to return true to upToDateWhen, but this would further complicate things anyway since it wouldn't run every time. As is, the inputs and outputs hashes between runs are completely different, almost entirely due to the different created/modified times on the files (due to the re-writing mentioned above). This causes them to always report being out of date.
  • Running the task at different times, but it can only be run once prepare....playservices....library task is about to run, which at that point is too late.

The only solution I can think of right now is to create an internal module project from the sdk's play services project with the stripped classes.jar substituted in. This is less than optimal though, as it unnecessarily abstracts the play services dependency to an entirely separate project and makes updating play services in the future very tedious.

Please let me know if anyone here is able to find a better solution.

@partyzan

This comment has been minimized.

Copy link

commented Aug 28, 2014

I am getting the following error as well, trying to figure put the gradle syntax... any ideas ?

Converting class java.lang.Boolean to File using toString() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use java.io.File, java.lang.String, java.net.URL, or java.net.URI instead.
@ChaitanyaPramod

This comment has been minimized.

Copy link

commented Sep 4, 2014

Works only after a clean for me 😩

@talobin

This comment has been minimized.

Copy link

commented Sep 5, 2014

@Takhion , and @partyzan. I had the same error and this solved my problem:
http://forums.gradle.org/gradle/topics/difference_between_copy_task_and_copy

Basically revised the delete task like what is shown in the article. Also make sure to delete any import that might have been automatically inserted at the beginning of your build.gradle file.
Let me know if it helps.

@gaurav-fueled

This comment has been minimized.

Copy link

commented Sep 17, 2014

Works

@Aracem

This comment has been minimized.

Copy link

commented Sep 17, 2014

You can find all the packages of google play here
http://developer.android.com/reference/gms-packages.html

@ladoleste

This comment has been minimized.

Copy link

commented Sep 17, 2014

My migraine just disappeared!

@ladoleste

This comment has been minimized.

Copy link

commented Sep 18, 2014

I've just updated my project to use gradle 0.13.0 and I'm getting this:

Error:(155) Execution failed for task ':MyProject:stripPlayServices'.

Cannot convert the provided notation to a File or URI: true.
The following types/formats are supported:
- A String or CharSequence path, e.g 'src/main/java' or '/usr/include'
- A String or CharSequence URI, e.g 'file:/usr/include'
- A File instance.
- A URI or URL instance.

@petermnt

This comment has been minimized.

Copy link

commented Sep 18, 2014

@ladoleste: apply the fix from @talobin
basically replace

delete {
   delete(file(new File(playServiceRootFolder, "classes_orig.jar")))
}

with

delete file(new File(playServiceRootFolder, "classes_orig.jar"))

And anyone got any insights on @hzsweers 's question? The additional build time is bugging me (although it beats not being able to build at all :))

@felipecsl

This comment has been minimized.

Copy link

commented Sep 19, 2014

thanks for the fix @frus

@ladoleste

This comment has been minimized.

Copy link

commented Sep 19, 2014

@frus: nice! thanks

@passsy

This comment has been minimized.

Copy link

commented Sep 22, 2014

Thanks!

@andaag

This comment has been minimized.

Copy link

commented Oct 5, 2014

@hzsweers did you ever find a solution?

I noticed right away that this happens on every build:
Input file src/build/intermediates/exploded-aar/com.google.android.gms/play-services/5.0.89/classes.jar has changed.
command: dx --dex --output src/build/intermediates/pre-dexed/debug/classes-bcce6309a4833bee1a1a4249e969fc418be68a9a.jar src/build/intermediates/exploded-aar/com.google.android.gms/play-services/5.0.89/classes.jar

@suarezjulian

This comment has been minimized.

Copy link

commented Oct 7, 2014

In case anyone needs this to make this work when using parallel builds (org.gradle.parallel=true inside gradle.properties), you need to add this snippet at the end :

    project.tasks.findAll {  it.name.contains(prepareTaskName) }.each { Task task ->
        stripPlayServices.mustRunAfter task
    }

I've created a fork with this modification here https://gist.github.com/TechFreak/f7ffcbfee5cfe318d31a: but I would prefer if the author added my modifications back to keep everything in one place

@erikandre

This comment has been minimized.

Copy link

commented Oct 8, 2014

When using the above code we are seeing that the added task (stripPlayServices) gets executed every time you build (due to classes.jar being updated) which in turn leads to the dex files being regenerated (adding more time to the build).

However, instead of adding a task to be run after the prepare task for the library you can add it to the prepare task itself (this way it will only run if the library is updated).

afterEvaluate { project ->
    Configuration runtimeConfiguration = project.configurations.getByName('compile')
    ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult
    // Forces resolve of configuration
    ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion
    String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library"
    Task prepareTask = project.tasks.findByName(prepareTaskName)
    File playServiceRootFolder = prepareTask.explodedDir
    // Add the stripping to the existing task that extracts the AAR containing the original classes.jar
    prepareTask.doLast {
        // First create a copy of the GMS classes.jar
        copy {
            from(file(new File(playServiceRootFolder, "classes.jar")))
            into(file(playServiceRootFolder))
            rename { fileName ->
                fileName = "classes_orig.jar"
            }
        }
        // Then create a new .jar file containing everything from the first one except the stripped packages
        tasks.create(name: "stripPlayServices" + module.version, type: Jar) {
            destinationDir = playServiceRootFolder
            archiveName = "classes.jar"
            from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) {
                exclude "com/google/ads/**"
                exclude "com/google/android/gms/games/**"
                exclude "com/google/android/gms/drive/**"
                exclude "com/google/android/gms/panorama/**"
            }
        }.execute()
        delete {
            delete(file(new File(playServiceRootFolder, "classes_orig.jar")))
        }
    }
}
@arriolac

This comment has been minimized.

Copy link

commented Oct 11, 2014

I'm including play-services in an android library project instead of the app module but the stripping doesn't seem to work, it works fine with I include play-services in the app module though. Any ideas why it's not working for android library projects?

@bmarty

This comment has been minimized.

Copy link

commented Oct 13, 2014

@erikandre proposal seems to work 👍 But why the last command delete is in another delete? typo?

@MarsVard

This comment has been minimized.

Copy link

commented Oct 13, 2014

Is it me or does this not work on android 2.3.x ? I keep getting a lot of:
W/dalvikvm﹕ Link of class 'LsomeLibraryClass' failed

but the same apk works fine on my 4.2.2 device

@gabin8

This comment has been minimized.

Copy link

commented Oct 15, 2014

it doesn't work on linux. I'm still getting error about dex limit

@ehssanh

This comment has been minimized.

Copy link

commented Oct 15, 2014

I can't get it to work either. My project is an android library project itself and I get this :

  • What went wrong:
    A problem occurred configuring root project 'Android_NEW_SDK_develop'.

    Failed to notify project evaluation listener.
    groovy.lang.MissingMethodException: No signature of method: org.gradle.api.internal.artifacts.result.DefaultResolutionResult.getAllComponents() is applicable for argument types: () values: []

@b1uebyte

This comment has been minimized.

Copy link

commented Oct 19, 2014

Is there any way to move this peace of code in separate file to keep build.gradle clean?

@Takhion

This comment has been minimized.

Copy link

commented Oct 20, 2014

This the result of all the changes discussed here, condensed in a gist: https://gist.github.com/Takhion/10a37046b9e6d259bb31

Working for me on:

  • Play Services 5.0.89
  • Android Gradle plugin 0.13
  • Gradle 2.1
@Takhion

This comment has been minimized.

Copy link

commented Oct 20, 2014

@b1uebyte use this:

apply from: 'strip_play_services.gradle'
@suarezjulian

This comment has been minimized.

Copy link

commented Oct 20, 2014

This script is NO longer necessary now you can use the new MultiDex functionality that is built right in the support library. More info: http://blog.osom.info/2014/10/multi-dex-to-rescue-from-infamous-65536.html

@chijikpijik

This comment has been minimized.

Copy link

commented Oct 21, 2014

I have an error:

Cannot get property 'moduleVersion' on null object

@Takhion

This comment has been minimized.

Copy link

commented Oct 22, 2014

@techfreak that's not true, by not using the script you would still include all the unneeded classes (unless you use Proguard), making your apk much bigger than needed! Plus, using MultiDex has an overhead and should be done only when really needed.

@robUx4

This comment has been minimized.

Copy link

commented Oct 24, 2014

I made this slight change to only do this stripping in debug builds. Since I ProGuard the code in other builds and I have no 64k limit issue

project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies')  && it.name.contains('Debug') }.each { Task task ->
@RichardGuion

This comment has been minimized.

Copy link

commented Oct 27, 2014

I tried this and it works well for me - I the same as @robUx4 and made it work only with Debug builds.

Does it actually continue to strip the play-services jar each time you compile, or is it smart enough to know it's already been done and skips that step? Just wondering if it does it each time how much it adds to compile time.

@tomrozb

This comment has been minimized.

Copy link

commented Oct 29, 2014

How to run this task from terminal for release build? It does work when first run from the Android Studio but after clean gradlew installRelease doesn't work any more (method ID not in [0, 0xffff]: 65536). I have to build the app at least once from Android Studio after each clean. Is there any way to strip play services from terminal without using IDE?

@CedricGatay

This comment has been minimized.

Copy link

commented Nov 13, 2014

Hi,
I updated this script to prevent restripping the play-services jar on each build if the configuration has not changed. See the fork at https://gist.github.com/CedricGatay/4e21ce855bd2562f9257.

Things to keep / exclude are declared at the top, and a simple file named after Play Services GAV identifier is put in build/intermediates/tmp as well as the stripped version of the jar to be swapped on next build if the content of the .marker file has not changed.

Seems to work so far in our current project, allows us to stay within the 64k limit by removing what's unnecessary.

Don't forget to use it in your build.gradle file this way :

apply plugin: 'com.android.application'
apply from: 'strip_play_services.gradle'
@slott

This comment has been minimized.

Copy link

commented Nov 28, 2014

With the latest 6.x of gms you might need to add the following to keep the class count to a minimum:

                exclude "com/google/android/gms/fitness/**"
                exclude "com/google/android/gms/wearable/**"
                exclude "com/google/android/gms/wallet/**"
                exclude "com/google/android/gms/cast/**"
                exclude "com/google/android/gms/ads/doubleclick/**"
                exclude "com/google/android/gms/ads/mediation/**"
                exclude "com/google/android/gms/ads/purchase/**"
                exclude "com/google/android/gms/ads/search/**"
                exclude "com/google/android/gms/analytics/ecommerce/**"
                exclude "com/google/android/gms/common/images/**"
@lemberh

This comment has been minimized.

Copy link

commented Nov 28, 2014

Can you explain for dummies where to put this script (in module build.gradle or in application build.gradle) and how to run it.
Because I put it in module build.gradle and get the following error
Error:(157) Execution failed for task ':phase-android-beta:stripPlayServices'.

Cannot expand ZIP 'D:\Projects\phase\phase-android-beta\build\intermediates\exploded-aar\com.google.android.gms\play-services\6.1.71\classes_orig.jar' as it does not exist.

@lemberh

This comment has been minimized.

Copy link

commented Nov 28, 2014

I fix it me helped @techfreak comment:
In case anyone needs this to make this work when using parallel builds (org.gradle.parallel=true inside gradle.properties), you need to add this snippet at the end :

project.tasks.findAll {  it.name.contains(prepareTaskName) }.each { Task task ->
    stripPlayServices.mustRunAfter task
}

I've created a fork with this modification here https://gist.github.com/TechFreak/f7ffcbfee5cfe318d31a: but I would prefer if the author added my modifications back to keep everything in one place

@Hoermann

This comment has been minimized.

Copy link

commented Dec 10, 2014

Google released GooglePlayServicesLib 6.5 you can now only compile the parts of GooglePlayServices you need http://android-developers.blogspot.de/2014/11/google-play-services-65.html

@octa-george

This comment has been minimized.

Copy link

commented Dec 11, 2014

Starting with version 6.5, of Google Play services, you’ll be able to pick from a number of individual APIs, and you can see which ones have their own include files in the documentation. For example, if all you want to use is Maps, you would instead have:

  compile 'com.google.android.gms:play-services-maps:6.5.87'

Note that this will transitively include the ‘base’ libraries, which are used across all APIs. You can include them independently with the following line:

  compile 'com.google.android.gms:play-services-base:6.5.87'

http://android-developers.blogspot.de/2014/12/google-play-services-and-dex-method.html

Google Play services API Description in build.gradle
Google+ com.google.android.gms:play-services-plus:6.5.+
Google Account Login com.google.android.gms:play-services-identity:6.5.+
Google Activity Recognition com.google.android.gms:play-services-location:6.5.+
Google App Indexing com.google.android.gms:play-services-appindexing:6.5.+
Google Cast com.google.android.gms:play-services-cast:6.5.+
Google Drive com.google.android.gms:play-services-drive:6.5.+
Google Fit com.google.android.gms:play-services-fitness:6.5.+
Google Maps com.google.android.gms:play-services-maps:6.5.+
Google Mobile Ads com.google.android.gms:play-services-ads:6.5.+
Google Panorama Viewer com.google.android.gms:play-services-panorama:6.5.+
Google Play Game services com.google.android.gms:play-services-games:6.5.+
Google Wallet com.google.android.gms:play-services-wallet:6.5.+
Android Wear com.google.android.gms:play-services-wearable:6.5.+
Google Actions Google Analytics Google Cloud Messaging com.google.android.gms:play-services-base:6
@AidenChoi

This comment has been minimized.

Copy link

commented Apr 13, 2015

If you don't want to use play services 6.5+ try this:

compile('com.google.android.gms:play-services:6.1.71') {
        exclude group: "com/google/ads/**"
        exclude group: "com/google/android/gms/analytics/**"
        exclude group: "com/google/android/gms/games/**"
        exclude group: "com/google/android/gms/maps/**"
        exclude group: "com/google/android/gms/panorama/**"
        exclude group: "com/google/android/gms/plus/**"
        exclude group: "com/google/android/gms/drive/**"
        exclude group: "com/google/android/gms/ads/**"
        exclude group: "com/google/android/gms/wallet/**"
        exclude group: "com/google/android/gms/wearable/**"
}
@jiahaoliuliu

This comment has been minimized.

Copy link

commented Jun 24, 2015

I am trying to get rid of the unused library for Google Play services 7.3 with the previous code but it does not work.

This is the code:

    compile ('com.google.android.gms:play-services:7.3.+') {
        exclude group: "com/google/ads/**"
        exclude group: "com/google/android/gms/ads/**"
        exclude group: "com/google/android/gms/analytics/**"
        exclude group: "com/google/android/gms/appindexing/**"
        exclude group: "com/google/android/gms/appinvite/**"
        exclude group: "com/google/android/gms/appstate/**"
        exclude group: "com/google/android/gms/cast/**"
        exclude group: "com/google/android/gms/drive/**"
        exclude group: "com/google/android/gms/fitness/**"
        exclude group: "com/google/android/gms/games/**"
        exclude group: "com/google/android/gms/identity/**"
        exclude group: "com/google/android/gms/location/**"
        exclude group: "com/google/android/gms/maps/**"
        exclude group: "com/google/android/gms/nearby/**"
        exclude group: "com/google/android/gms/panorama/**"
        exclude group: "com/google/android/gms/plus/**"
        exclude group: "com/google/android/gms/safetynet/**"
        exclude group: "com/google/android/gms/wallet/**"
        exclude group: "com/google/android/gms/wearable/**"
    }

And I still can see them in the console:

:app:prepareComGoogleAndroidGmsPlayServices730Library
:app:prepareComGoogleAndroidGmsPlayServicesAds730Library
:app:prepareComGoogleAndroidGmsPlayServicesAnalytics730Library
:app:prepareComGoogleAndroidGmsPlayServicesAppindexing730Library
:app:prepareComGoogleAndroidGmsPlayServicesAppinvite730Library
:app:prepareComGoogleAndroidGmsPlayServicesAppstate730Library
:app:prepareComGoogleAndroidGmsPlayServicesBase730Library
:app:prepareComGoogleAndroidGmsPlayServicesCast730Library
:app:prepareComGoogleAndroidGmsPlayServicesDrive730Library
:app:prepareComGoogleAndroidGmsPlayServicesFitness730Library
:app:prepareComGoogleAndroidGmsPlayServicesGames730Library
:app:prepareComGoogleAndroidGmsPlayServicesGcm730Library
:app:prepareComGoogleAndroidGmsPlayServicesIdentity730Library
:app:prepareComGoogleAndroidGmsPlayServicesLocation730Library
:app:prepareComGoogleAndroidGmsPlayServicesMaps730Library
:app:prepareComGoogleAndroidGmsPlayServicesNearby730Library
:app:prepareComGoogleAndroidGmsPlayServicesPanorama730Library
:app:prepareComGoogleAndroidGmsPlayServicesPlus730Library
:app:prepareComGoogleAndroidGmsPlayServicesSafetynet730Library
:app:prepareComGoogleAndroidGmsPlayServicesWallet730Library
:app:prepareComGoogleAndroidGmsPlayServicesWearable730Library

What am I doing wrong?

@cyberrob

This comment has been minimized.

Copy link

commented Nov 28, 2015

As of Play service 8.3.0 you can selectively choose which individual library used in the app. So there's no need to exclude anymore.
https://developers.google.com/android/guides/setup#split

@andanicalik

This comment has been minimized.

Copy link

commented Dec 1, 2015

I paste it to the bottom of app's build.gradle file and it failed : "Cannot get property 'moduleVersion' on null object"
What should I do ?

@FTExplore

This comment has been minimized.

Copy link

commented Mar 7, 2016

Cannot get property 'moduleVersion' on null object. I got this problem and the sync failed....

@steewsc

This comment has been minimized.

Copy link

commented Jun 13, 2016

Cannot get property 'moduleVersion' on null object. I got this problem and the sync failed....

at
ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion

Happened to me to, so I printed it:
`

ModuleVersionIdentifier module = resolution.getAllComponents().find {
    System.out.println("MODULE NAME ====> " + it.moduleVersion.name);
    /*it.moduleVersion.name.equals("play-services")*/
}.moduleVersion

`
....
MODULE NAME ====> recyclerview-v7
MODULE NAME ====> core
MODULE NAME ====> gson
MODULE NAME ====> hirondelle-date4j
MODULE NAME ====> play-services-analytics
:app:preBuild
:jawampaLib:preBuild
....

As You can see, there is no "play-services", but "play-services-analytics" (in my case) :)

@androuis

This comment has been minimized.

Copy link

commented Jul 13, 2016

Same happens in my case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.