144

I have a sample project, with the following setup:

/root
  + Pure Java Lib
  + Android Test Lib
  + Android Test Project

Where the 'Test Project' is dependent on the 'Test Lib', and the last depends on the 'Pure Java Lib' Compiling the project and launching this setup works just fine.

I'm now thinking about importing my previous Eclipse workspace and work with Android studio, the problem is the project setup is different, and I would like to keep it this way.

for example if to use the previous example:

/root
  + Android Test Lib
  + Android Test Project

/Some Other folder (another repository for example)
  + Pure Java Lib

I've tried many configurations, but I didn't find a way to reference a project outside the scope of the parent folder ('root' in the example case).

In many platforms/modules you can use the '..' to move up in the folders but this didn't work for me, perhaps I've used it wrong.

Does anyone know how this can be achieved with Gradle?

UPDATE

I'll try to be more generic:

/C:/

  /Project A
    + Module 1 - Pure Java
    + Module 2 - Android Test Lib
    + Module 3 - Android Test Project

  /Project B
    + Module 1 - Pure Java
    + Module 2 - Pure Java
    + Module 3 - Pure Java

I would like to use Module 1 of project B, in project A.


UPDATE: 09-03-19

I saw this now and I must update... after almost 6 years, today I am wiser, and I can definitely say the problem was me misunderstanding the concept of "Source of truth".

While having one ref to a library is a nice to have concept.. and may seem like the a "Source of truth", the REAL "Source of truth" would be the version of the code each project is using of that library, cause the library by itself has versions.. many versions an the "Source of truth" is relative to the project which is using the library.

The correct way would be to use what most developers do not like, and that is git submodules, and yes duplicate the sources in each project cause most chances each project uses a different version of the code.

You would need however to aim for all of your projects to use the latest and greatest version of all your libraries.. which is a challenge by itself

The reason this is the right way to develop a project with library sources is that this scales... you can have hundreds of project each with its own library configuration.

TacB0sS
  • 10,106
  • 12
  • 75
  • 118
  • 4
    I see this question gets some attention... After trying really really hard, I gave up on the Android studio for now, since the complexity of the setup I was trying to construct was just too much, and building my final project was doable, but highly unstable. with every launch of the Android studio I had to set some parameters again, and manually cause the build to work. it has been about two months since I gave up, and I hope things are better now! – TacB0sS Oct 14 '13 at 19:09
  • Approach 2 here explains how to do this very easily: http://stackoverflow.com/questions/25610727/adding-external-library-in-android-studio – Doron Ben-Ari May 14 '16 at 16:56

6 Answers6

225

Assuming that Some Other Folder is a gradle project you could add something like the following to your settings.gradle file:

include ':module1'
project(':module1').projectDir = new File(settingsDir, '../Project B/Module 1')
Ethan
  • 6,883
  • 3
  • 33
  • 41
  • 1
    The someOtherFolder points to a project folder and in it there are modules, which I'm interested to add as modules to the Android Lib project – TacB0sS Jul 05 '13 at 18:35
  • The settings dir points to 'root' I need to get a level higher, to another module in another project. – TacB0sS Jul 05 '13 at 18:37
  • could you add the submodules after that? include ':someOtherFolder:proj1' – Ethan Jul 05 '13 at 18:42
  • lets assume its proj1, ':someOtherFolder:proj1' results in error since the 'Some Other Folder' is on the same level as 'root' – TacB0sS Jul 05 '13 at 18:44
  • 1
    updated with some details. settings.gradle should be in /Project A – Ethan Jul 05 '13 at 19:01
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33013/discussion-between-tacb0ss-and-ethan) – TacB0sS Jul 06 '13 at 23:44
  • Thanks Ethan, for your answer, it helped a lot. However, I am having another problem, using this solution. If Project A settings.gradle has this projectDir defined in it where it reference Project C. Then when Project B references Project A, gradle fails to build because it can't find compile project(':ProjectC') ->inside build.gradle of project A when building Project B who now depends on Project A because that is in a different settings.gradle. Project B shouldnt need to be aware of Project C. How can I include the dirs that were established in Project A's settings when building Project B – Sam Jan 09 '14 at 20:50
  • @Sam you should probably have that where you share a single settings.gradle. If you put all three in the settings.gradle file that should let you do it. If that doesn't work create a question and link the question here and I'll look at it – Ethan Jan 13 '14 at 00:03
  • Make sure the external module is marked as a library, else you won't be able to reference anything it. I was stuck on this for awhile. – RobB Mar 10 '14 at 16:39
  • @Ethan do I need to add `compile project(':module1')` to my build.gradle or any other configuration? – Niklas Aug 12 '14 at 19:21
  • To get this to work I also had to add the library to the main applications dependencies as indicated in @Varundroid's answer – bcorso Aug 18 '14 at 18:05
  • 5
    Great answer. In AS 1.0.2, I also needed to do the following: Right click module -> Open Module Settings -> Dependencies -> + (bottom), select Module Dependency, select your library from the list, click ok :) – T.Coutlakis Jan 11 '15 at 22:51
  • This answer should be to the question: How To Migrate From Maven to Gradle keeping folder structure. THANK YOU. – Alejandro Zurcher Sep 28 '15 at 12:58
  • @Niklas yes, you do I also had to delete the .gradle directory of my main project for this to work – Lakedaemon Aug 14 '17 at 09:28
  • i get `Compilation is not supported for following modules: app. Unfortunately you can't have non-Gradle Java modules and Android-Gradle modules in one project.` – the_prole Dec 19 '19 at 19:25
  • If we include submodules, studio sync is successful. but the modules appear very messy, sometimes appear , sometime disappear and not expected hierarchy. `include ':pathA:module1' project(':pathA:module1').projectDir` – Victor Choy Jul 26 '21 at 09:25
  • PS: Studio version is 4.1.1 and 4.2.2 – Victor Choy Jul 26 '21 at 10:09
54

You have to put in your file settings.gradle this lines:

include ':module2'
project(':module2').projectDir = new File(settingsDir, '../Project 2/Module2')

Then you have to add in your builde.gradle (Module: app) in the dependencies tree, this line:

implementation project(':module2')

or go into the Project Structure > app > Dependencies, click on Add, choose 3 Module Dependencies and select your module

Dario Brux
  • 1,871
  • 1
  • 17
  • 15
  • 2
    If you have problems with referencing the library's classes from the main app, this is because the library probably comes in different variants. So, just specify the dependency in a proper way: `compile project(path: ':library', configuration: 'variant')`. Here, `variant` consists of `flavor` and `buildType` as defined by the library's `build.gradle` file. For example, if you want `release` build type of the library in a `develop` flavor, then `variant` is `developRelease`. – Sevastyan Savanyuk Aug 09 '17 at 07:44
9

With Gradle 1.10 (don't know what other versions this will be valid for) this is what I came up with based on a response given here http://forums.gradle.org/gradle/topics/reference_external_project_as_dependancy

I have an api library project, a common library project and the main app project. Each is a stand-alone development project and the two libraries are meant to be shared between multiple apps.

In settings.gradle for the common project:

def apiLibDir = file('../android-api/android-api-lib')
def rootProjectDescriptor = settings.rootProject
settings.createProjectDescriptor(rootProjectDescriptor, 'android-api-lib', apiLibDir)
include ':android-api-lib'

Then in the main app project settings.gradle:

def apiLibDir = file('../android-libs/android-api/android-api-lib')
def rootProjectDescriptor = settings.rootProject
settings.createProjectDescriptor(rootProjectDescriptor, 'android-api-lib', apiLibDir)
include ':android-api-lib'

def commonLibDir = file('../android-libs/android-common/android-common-lib')
settings.createProjectDescriptor(rootProjectDescriptor, 'android-common-lib', commonLibDir)
include ':android-common-lib'

In each of the respective build.gradle files you just reference them by the name you gave them in the settings.createProjectDescriptor like you would any other project dependancy:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':android-api-lib')
    compile project(':android-common-lib')
}

This seems to work. It didn't even throw an error for multiple DEX files defining the api library, I suspect because it was all part of the same build process and Gradle was smart enough to figure it all out.

alphonzo79
  • 938
  • 11
  • 12
  • 2
    I keep trying this but the problem is that the dependencies in the respective library seem to never get loaded. So if I have just the library open it seems fine but when I try it from the main app, it says all the imported libraries are missing. – Czechnology Aug 11 '14 at 19:03
  • @Czechnology Had the same problem. Solved it. See my comment for this answer: https://stackoverflow.com/a/29603354/7408927 – Sevastyan Savanyuk Aug 09 '17 at 07:47
8

Right click on project - Select "Open Module Settings" - Select "Modules" in left pane - Click on "+" symbol on top - Choose "Import Module".

After importing Module. You need to add it as a dependency for your current project.

Keep "Modules" Selected in left pane and click on your project - Now Go in dependencies tab and click on "+" symbol that is located at bottom - Choose third option "Module Dependencies" and if you have imported your project correctly, it will show you the all available module that can be added as a dependency to your current project.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Varundroid
  • 9,135
  • 14
  • 63
  • 93
  • This almost work... the project cannot be build because the output of the dependency module is not added to the build.gradle file, which is exactly my original issue. – TacB0sS Jul 05 '13 at 00:38
  • I think with gradle, you need to put all the projects in the same root folder. Try that. Put the project you want to add as a dependency in the same folder as your current project. – Varundroid Jul 05 '13 at 04:30
  • This is what nobody wants to do but ATM if you wanna work with Android Studio, this is the way to make things work. Another alternative way which i am following is, i create project in Intellij setup all dependencies and then import that project to Android studio, by doing this i am forcing Android Studio to use ant build system rather than Gradle. Hope it helps. Cheers!! – Varundroid Jul 07 '13 at 07:26
  • 1
    @Varundroid, the solution is to first import a reference to the stand-alone library using Ethan's answer. Then add the module to the main app's dependencies using your answer. This allows you to reference the same library in multiple apps without having to duplicate the library code. – bcorso Aug 18 '14 at 18:08
1

I re-ask this question in a way which entails the original posters' intentions at How do we reference custom Android and Java Libraries living outside the directory of our Main Android Project?

There I answer my own question. At core my answer uses @Ethan's (the author of the chosen answer in the current thread) gradle coding insight. But my answer also navigates some other gotchas and provides a detailed step by step example.

John Bentley
  • 1,676
  • 1
  • 16
  • 18
-1

As Ethan said, if you add this to your settings.gradle, it will add an external project to Android Studio (in this example, it's in the parent folder):

project(':../ProjectB/:module1')

Then, to add it as a dependency of one of your projects, just add it in the build.gradle of that project as another dependency like this (you can also do it graphically as in here):

compile project(':../ProjectB/:module1')
Community
  • 1
  • 1
Yair Kukielka
  • 10,686
  • 1
  • 38
  • 46