69

Question as in title. A similar question was asked here, and the only workaround that time was to publish the project into a local Maven repository.

Is this problem fixed (as claimed by some) in Android Studio 0.5.+? In its release note there is a statement that says "Support for source folders outside the module content root". Does that mean we can finally import the library from outside the project folder?

I tried File->Import Project.. but it doesn't work.

EDIT 2: See accepted answer for latest solution (as of 0.8.+)

EDIT:

My project directory structure has only one module main which looks like this

MyApp
    main
        build.gradle
        src
    build.gradle
    settings.gradle

The library project directory has only one module named like lib (they are all auto-generated when creating a new library project)

MyLibrary
    lib
        build.gradle
        src
    build.gradle
    settings.gradle

The following line is added into MyApp/settings.gradle:

include ':main', '..:MyLibrary'

The following is added into MyApp/main/build.gradle:

dependencies {
    compile project(':..:MyLibrary')
}

The result is the following error:

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':main'.
> Configuration with name 'default' not found.

As a side note, the library project MyLibrary itself can compile without error. The problem seems to be settings.gradle not being able to recognize the library project structure.

Community
  • 1
  • 1
Neoh
  • 15,906
  • 14
  • 66
  • 78

6 Answers6

88

(as of version 2.1+):

Below are the steps that I took to share library source outside of the project directory. Instead of plain Java library, my code is compiled as Android module, but that library module is not contained inside the main project. It is fine with me as long as there are no code duplications and I only need to maintain one set of library code for all projects:

  1. File->new Project. Give a name to your library project (here I use LibraryProject). Continue the remaining steps to create a normal project (since this is intended as a library, I chose "add no activity")

  2. By default, Android studio creates the module named as "app" inside the project folder. To prevent names collision with the actual application module, rename the module to something else (Right click "app" module at left panel->Refactor->Rename).

  3. In the build.gradle inside your library module folder, change the top line

    apply plugin: 'com.android.application' to

    apply plugin: 'com.android.library'

and then remove the "applicationId" line under "defaultConfig". Also, since this is a library, remove the xlmns:... namespace and <application ..> body from Manifest.xml as well. That's all for the library part. Now, to create/modify your main application:

  1. If it is a new project, first create new project File->new Project->ApplicationName.

  2. Open settings.gradle (there should only be one such file in every project) and include the following line (note the missing leading semi-colon in library module):

    include ':app', '..:LibraryProject:yourLibraryModule'

  3. Then go to File->Project Structure.

  4. Under the tab "Dependencies" click the green "+" button at right. Select "Module dependency". Choose your library module, then click OK.

You should now be able to use the library classes in your application.


ALTERNATIVE METHOD If, for some reason, there are still problems with the above method, you can try the following (suggested in [here][1]):

  1. Repeat steps 1 to 4 above. By default the main and external (library) project look something like this:

    /MainProject + build.gradle + settings.gradle + app/ + build.gradle + src/

    /LibraryProject + build.gradle + settings.gradle + app/ + build.gradle + src/

  2. As usual, refactor the modules name (in android studio right-click module->refactor->rename) to something less confusing, such as

    /MainProject + build.gradle + settings.gradle + MainModule/ + build.gradle + src/

    /LibraryProject + build.gradle + settings.gradle + LibraryModule/ + build.gradle + src/

  3. Modify the settings.gradle in MainProject:

    include ':LibraryModule', ':app' project(':LibraryModule').projectDir = new File(settingsDir, '../LibraryProject/LibraryModule') Sync the project and you're done.


Note on Proguard

Currently you should not use a proguard on external library projects/modules. Instead, you replace the following (original answer [here][2])

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
    }
    debug {
        minifyEnabled false
    }
}

with the following (in build.gradle of the library):

buildTypes {
    release {
        consumerProguardFiles 'proguard-project.txt'
    }
}

where proguard-project.txt is the file that contains the proguard rules for your library project. [1]: https://stackoverflow.com/a/17490233/1919013 [2]: https://stackoverflow.com/a/31031491

starball
  • 20,030
  • 7
  • 43
  • 238
Neoh
  • 15,906
  • 14
  • 66
  • 78
  • 1
    Can you please provide an archive with a skeleton of your main library & projects? Or you can explain how to make the library project directory structure? When I make a library project, AS creates more deep structure. I tried to create directories like you did, but AS reports about error 'Bad pathname' in the exploded-aar directory. I'm tried a ton of variants during last 2 hours, but without success. :( – Vlad Kuts May 16 '14 at 16:20
  • 1
    @ScottBarta. I'm on Android Studio 0.6.1. I can't get this to work even after following the careful instructions of Scott Barta and Neoh. I'm stuck with the "Error: Configuration with name 'default' not found.", even after rearranging MyLibrary's file structure according to Neoh's specs (and designating MyLibary with "apply plugin: 'android-library'" in MyLibrary's build.gradle). In the end I think this issue is better addressed by the Android Studio developers (Scott Barta you seem to such a dev) continuing their good work so that it becomes a straightforward affair . – John Bentley Jun 13 '14 at 18:36
  • 3
    This solution won't work if the imported module depend on other external module. In this case look at the solution described here http://stackoverflow.com/questions/17479076/android-studio-add-external-project-to-build-gradle – Rémy DAVID Dec 01 '14 at 11:47
  • 3
    the last hint `project(':LibraryModule').projectDir = new File(settingsDir, '../LibraryProject/LibraryModule')` made my day – injecteer Nov 03 '15 at 23:29
  • I've been struggling with this all afternoon. What unlocked it for me was the realization that the project reference in `settings.gradle` **must** reference not only the project directory (though this is confusingly enough to make it appear in the project navigator) but **also** the module name (which is a good reason to rename it from `app` to something else). My test `settings.gradle` file looks like this: `project(':core').projectDir = new File('../FoobarCore/core')` – Brian Rak Jul 26 '19 at 23:46
  • This solution generates tons of bugs since Android Studio 3.1. When you switch projects it seems that Android Studio somehow remembers about the previous project and tries to load both. You have to manually delete .iml files and .idea folders every time you switch before it works, which is cumbersome. – Dalmas Sep 22 '19 at 07:24
  • The alternative method worked for me on Android Studio 4.0.1 – Sérgio Domingues Jun 06 '21 at 03:34
9

Yes, it works now in 0.5.0. There isn't a friendly UI to it (Import Project isn't what you want, as that creates an entirely new project; Import Module is still broken; see https://code.google.com/p/android/issues/detail?id=62122), but you can set up your build files to make it work.

Let's say you have a directory structure that looks like this:

MyApp
    appmodule
        build.gradle
            src
                main
                    java
    build.gradle
    settings.gradle
MyPlainJavaLibrary
    build.gradle
    src
        java

Note that MyPlainJavaLibrary isn't underneath the MyApp directory in the filesystem.

Set up your settings.gradle file like so:

include ':appmodule', '..:MyPlainJavaLibrary'

and include a dependency to it in build.gradle like this (don't forget the leading colon):

dependencies {
    ...
    compile project(':..:MyPlainJavaLibrary')
}

This works for me. In my Project viewer, I now see MyApp and MyPlainJavaLibrary as two root-level module directories in the view, and I can make java import statements work across module boundaries and such.

Note that in this default setup, this shared module will only have a single build output folder that will be shared among all the projects using it. This may or may not be what you want. If you'd like to have a different output directory for each project using the shared module, you can probably do some magic with the output directory in the sourceSet; if you want help with this, I'd recommend trying it out on your own and posting a question with details on your work if you get stuck.

You can only have one settings.gradle file per project, so this isn't going to take a whole other multimodule Gradle project and bring in all the modules in one fell swoop; you'll need to bring them in individually. However, it should satisfy the use case of using a module in multiple projects.

Scott Barta
  • 79,344
  • 24
  • 180
  • 163
  • 4
    I assume the dependency is added into module `build.gradle` not project root `build.gradle`. I got the following error:`A problem occurred configuring project ':main'.` `> Configuration with name 'default' not found.` – Neoh Mar 08 '14 at 13:21
  • @Neoh I had the same error, resolved it by using **compile project(':MyPlainJavaLibrary')** – omermuhammed Mar 12 '14 at 03:53
  • @omermuhammed That only seems to work when you place the `MyPlainJavaLibrary` inside the project folder. My question is asking about including a library source from outside the project folder. – Neoh Mar 12 '14 at 04:29
  • 1
    I am new to Android Studio but I have set up my app and library as sibling modules in the project. There seems to be an open issue with Android Studio currently not allowing Module imports from outside the project, something you are trying to do. The other approach I saw was making the library project binary be saved to mavenlocal() (a local maven repo) and then using it in the app. Havent been able to do this, for now atleast. – omermuhammed Mar 12 '14 at 04:59
  • @omermuhammed you are misunderstand the point of this thread. The 'MyPlainJavaLibrary' needs to be outside of the current project so that it can be shared with other projects. – Martin Konecny May 07 '14 at 03:21
  • 3
    @Neoh I was able to solve the "default not found problem". In my case, I had changed ```compile project(':..:MyPlainJavaLibrary')``` to ```compile project(':..:MyPlainJavaLibrary:app')``` in build.gradle and ```include '..:lucovaAndroidSDK'``` to ```include '..:lucovaAndroidSDK:app'``` in settings.gradle. – Martin Konecny May 07 '14 at 14:25
  • @MartinKonecny I follow your method just changed `compile project(':..:MyLibrary')` to `compile project(':..:MyLibrary:library')` because my library has `library` and `sample` module. – Arst Nov 07 '14 at 03:47
  • I have difficulty in using GIT for the library configured in this way. Only a part of GIG functions are available for the library. Any tip will be greatly appreciated. – Hong Jul 30 '15 at 13:49
1

I wanted to do something similar for my Android Wear project, where you have mobile and wear modules. In Android Studio 1.5.1, you can do File->New->Module and pick Android Library as your module. This will take care of many of the settings described above and put your library inside your existing Android Wear project.

Opus1217
  • 723
  • 4
  • 17
1

To make full use of Android Studio, I would recommend initially creating a normal android project. Then, within that project, add a Module "android library" type, and (optionally) a "java library" (if you have code you want to use that may be common to Android applications and to server side code).

Using this mechanism, you do not need to manipulate and modify gradle and manifest files.

ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
1

I also wanted to use the same collection of classes across projects, I found an easier way.

Put the class files you want to use in their own folder outside all of your project folders.

Make a symlink(linux) or shortcut(win) to this folder and copy it to:

~/src/main/java/com/yourco/yourproject/

in each of your project folders.

You now have a package of all your commonly used classes synced on all your projects. You're welcome.

xy2
  • 6,040
  • 3
  • 14
  • 34
  • This is the fastest way in the world as of now. Very useful if we have local code files to share. Works immediately. – Jaya Prakash Aug 26 '22 at 14:23
0

You are able to use module(as a shared source code base)apply plugin: 'com.android.library' in the project.

[Project vs Module]

yoAlex5
  • 29,217
  • 8
  • 193
  • 205