简体   繁体   中英

Android Studio Gradle External Library Project

Ok, I realize that Gradle and Android Studio seem to think that all Library Applications are built for one project and one project only, but that is not the case. I have many shared Library Applications with common purposes that are shared throughout the organization. Gradle does not seem to be very accomodating to this desired solution. Can someone offer any insight?

My current Structure at a very rudimentary level is like this:

|--Directory
|  |--PROJECT A
|     |---Module 1
|  |--Project B
|     |---Module 2
|  |--Project c
|     |--Module 3

///////////////////////////////////////////// My Current dependency structure is like this: /////////////////////////////////////////////

Project A : (FYI, Builds Just Fine)

Project A's settings.gradle

include ':Module 1', ':Module 2'
project(':Module 2').projectDir = new File('../Project B/Module 2')

Module 1's build.gradle

dependencies {
    compile project(':Module 2')
}

Project C: (FYI, BROKEN)

Project C's settings.gradle

include ':Module 3', ':Module 1'
project(':Module 1').projectDir = new File('../Project A/Module 1')

Module 3's build.gradle

dependencies {
    compile project(':Module 1')
}

Breaks: Cannot resolve Module 2 inside of Module 1's build.gradle file.

This is because the directory structure for Module 2 is established inside Project A's settings.gradle so Project B has no idea where to render this from.

I understand that I can add

project(':Module 2').projectDir = new File('../Project B/Module 2')

to Project C and everything will work just fine. However Project C doesn't use or know about Module 2. I want other developers to have the freedom to use my common shared library project without having to dig in and see what library projects I used and include those in their settings as well. How can I specify my own dependency directory structure in the build.gradle instead of the settings.gradle to make it accessible to all that use it?

On a second note, but similar topic. I'm having the exact same issue with JAR files. If i specify a REPO in a Library Project's build.gradle like: myRepo1 and have a myJar1. Then when that library project is used in a parent project that doesn't define the repo that contains the jar in the library projects dependeny section, it fails to resolve the jar file from the library project when compile project(':libproject') is used. I have to duplicate the repo pointers in the parent's build.gradle file as well so that the libproject will build from the parent app. Any help on this one would be appreciated as well. As not every repo is used in every app so this can become redundant.

Ok this is a really old post, but still gets traction so let me update 3 years later since I originally wrote it lol.

Shout out to CommonWare who had the right best practice idea right from the start, but didn't provide an answer to mark up.

Let me start by saying that using project references like I was doing above should be limited to development stages only and should only be if the library project is also in development stage at the same time as the main project. Otherwise a dependency management server like Nexus, Apache Archiva, or S3 with Maven directory structure or equivalent would be preferred. I have learned many ways to manage dependencies since this, including transitive dependency management.

My preferred method is to deploy artifacts with POM files to Apache Archiva and then use these dependencies within the parent project instead of using relative paths to reference code projects now. This is the first choice.

However, if you are too new to dependency management and choose not to have a server for this purpose, you may package your AAR files or JAR files and put them in one centralized repo like artifact_repo and have everyone include that repo at the same folder structure and reference them relatively, but this is not good practice so I would steer clear if you can.

You can also take the artifacts and nest them in you libs directory and bring them in that way if you would like, but it becomes more of a manual update process which some people like and others do not.

Now this opens a whole different set of issues that you need to handle.

Transitive Dependencies and Child Repo pointers. For example, if you wrapped your own Crash Reporting Library around Fabric or Hockey or other hoping to make it easy to trade libraries later, then you have found that the repo pointer has to live in the parent build.gradle files or the transitive dependencies are not found.

You could of course use one of those hacky Fat_AAR or Fat_JAR scripts that works "sometimes" until updated gradle then they break again until someone hacks it back together, but this is also poor practice as you are creating potential mismatch dependencies on support or other important child libraries and the "exclude transitives" only works if you are using pom files to control the transitives and not making the AAR or JAR file fat. So you are limiting your ability to control the dependencies.

So what i have finally come to terms with is that transitive dependencies should be managed through POM files to allow excluding or including without nesting into children libraries. Also libraries that require repo pointers inside of them, should probably not exist as they require parent boiler plate, introduce room for human error and typically don't save much time on wrapping analytics or crash libraries for example or you start getting into json configs that need to live in parent files for PUSH or other reasons. Just avoid it.

So long story short lol. Stick to dependency management tools they way they were intended to be used and you will be fine. It is when you are new to it or start getting hacky that you run into ugly code and ugly problems. Hope this encourages someone to do it the right way :)

One last thing :). I have recently started writing Gradle Plugins to manage my versions and dependencies as a separate file so that I can use intellisense to pull in dependencies and make sure all support, gms, and tool versions are the same across all projects. You can even copy down live templates with your plugin to enable intellisense for Gradle to work with your stuff. It's not too bad to do. Best of luck and happy Gradling :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM