12

I am using the latest Android Studio 3.0.0-beta6 to build my Android project and there's this dependency issue. Gradle encouraged me to replace all compile's with implementation's. Here's my project structure:

Project:

  • module1

    • module2

Module1 depends on some libraries, module2 depends on module1. However, the libraries from module1 are not visible in module2. I don't want to copy-paste dependencies and would rather have the library dependencies declared only once. Is there a simple solution to this? Thank you.

module1's build gradle:

dependencies {
    ....
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    ...
}

module2's build gradle:

implementation project(':module1')
5
  • so to understand better you have some common dependencies for modules 1 and 2 correct? Commented Oct 2, 2017 at 13:32
  • yes. 1 and 2 have common dependencies. Commented Oct 2, 2017 at 14:06
  • this is easy!! Just put your common dependencies in the Root Project -> build.gradle and they will apply for all your modules Commented Oct 2, 2017 at 14:11
  • But I don't want it in all my modules, just these 2. Commented Oct 2, 2017 at 14:13
  • check my updated answer Commented Oct 2, 2017 at 14:36

2 Answers 2

14

Old question, but it sounds to me like what you're after is simply to use api instead of implementation in your gradle files?

If a module X declares an api dependency, it's transitively available to any other module that depends on X. If it however declares an implementation dependency, the classes from that dependency is put on the class path for module X, but not for any modules in turn depending on module X.

From Gradle's documentation:

Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers. Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath.

So to be concrete:

module 1:

dependencies {
    ....
    api 'io.reactivex.rxjava2:rxandroid:2.0.1'
    api 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    ...
}

module 2:

implementation project(':module1')

Isn't this the simplest solution to what you're trying to do?

Sign up to request clarification or add additional context in comments.

2 Comments

What if api is not an options for some reason
The other answer if fine, but this should be the accepted answer. Upvoted!
10

In your Root Project -> build.gradle you should have something like:

allprojects {
    repositories {
        jcenter()
    }
}

Add dependencies there!!

UPDATE

If you do not want all your modules to have the common dependencies but only specific modules then do this:

  1. Create a folder in your Root Project/gradleScript
  2. Create a .gradle file in this folder (e.g. gradleScript/dependencies.gradle) that looks like:

    ext {
    
    //Version
    
    supportLibrary = '22.2.1'
    
    //Support Libraries dependencies
    supportDependencies = [
            design           :         "com.android.support:design:${supportLibrary}",
            recyclerView     :         "com.android.support:recyclerview-v7:${supportLibrary}",
            cardView         :         "com.android.support:cardview-v7:${supportLibrary}",
            appCompat        :         "com.android.support:appcompat-v7:${supportLibrary}",
            supportAnnotation:         "com.android.support:support-annotations:${supportLibrary}",
    ]
    }
    
  3. In your root project build.gradle add this line:

    buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
    }
    
    // Load dependencies
    apply from: 'gradleScript/dependencies.gradle'
    
  4. In your modules accordingly add this:

    // Module build file
    
    dependencies {
        //......
        compile supportDependencies.appCompat
        compile supportDependencies.design
    }
    

Hope this helps!!!

3 Comments

Such a nice solution. Can we use environment variables in apply from part? Like apply from: '%projects_root%/gradleScript/dependencies.gradle'
the gradleScript folder is in your project dir directly. where the app module folder is. If you want to prevent it from others to see it then add it in .gitignore I would suggest. But if you really want environment variables you can try this: for example : println System.getenv('JAVA_HOME')
this approach doesn't show upgrade version warning miro.medium.com/max/3708/1*hgOycRk5Rds-gOS80Hz6IA.png

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.