A.Alqadomi A.Alqadomi - 4 months ago 16
Android Question

Android Gradle Why do we need "allprojects"?

I faced a problem when I tried to add Gson to my existing Android gradle project.

The exception was something like this


" failed to resolve:com.google.code.gson:gson:2.3.1"


My build.gradle

buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
}
}


apply plugin: 'android'

dependencies {
compile 'com.google.code.gson:gson:2.3.1'
.
.


After some searching and trial and error I found that you need to add the following to fix the issue:

allprojects {
repositories {
jcenter()
}
}


Why to do we need to reference the jcenter two times and why was the "allprojects" important to fix this issue ?

Answer

After some searching and trail and error i found that you need to add the following to fix the issue

Only if you have a traditional Android Studio project, where you have the application divided into modules (e.g., app/). What is really required is for the module to know where to pull dependencies from.

Why to do we need to reference the jcenter two times

The repositories closure in your buildscript closure says "these are the artifact repositories from which to pull Gradle plugins and other dependencies listed for the buildscript closure itself".

The repositories closure that you have in allprojects closure says "these are the artifact repositories from which to pull your own application dependencies".

In a traditional Android Studio project, the allprojects closure goes in the build.gradle file that is in the project root directory. allprojects says "everything in this closure, please apply to the Gradle configuration for all of the modules in this project, such as that app/ module over there".

Now, your build.gradle snippet in your question hints that perhaps you do not have a traditional Android Studio project, but instead have one where you do not have an app/ module and you have only one build.gradle file. In that case, allprojects itself is not necessary (as there are no modules), but you still need to specify what the repositories are.

For example, here is a build.gradle file from a module-less project:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.0'
    }
}

apply plugin: 'com.android.application'

repositories {
    mavenCentral()
    maven {
        url "https://repo.commonsware.com.s3.amazonaws.com"
    }
}

dependencies {
    compile 'de.greenrobot:eventbus:2.4.0'
    compile 'com.android.support:support-v13:21.0.3'
    compile 'com.commonsware.cwac:wakeful:1.0.+'
}

android {
    compileSdkVersion 19
    buildToolsVersion "21.1.2"

        defaultConfig {
            targetSdkVersion 17
        }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}

Here, in addition to a repositories closure inside buildscript (to define where the plugins come from), I have a top-level repositories closure, to define where the top-level dependencies come from.

Comments