1

I have an Android project set up so that uses module system as a way to "plug-in" features selectively.

Here's what the project hierarchy looks like:

  • app
    • manifests
    • java
    • assets
    • res
  • module1
    • manifests
    • java
    • assets
    • res
  • module2

    • manifests
    • java
    • assets
    • res
  • ...

Basically what I want to do is selectively include these module1 and module2 so that I can decide what module to include when building.

I already have achieved this by adding

compile project(:module1) to build.gradle

and setting the settings.gradle file as follows:

include ':app', ':module1'

But here's the real question: Honestly I don't know why I have to modify both of these files.

Technically the build.gradle file describes the dependency between modules, which means if I included :module1, doesn't this imply that I am including this in the build?

Is there a way to make a change to a single file, and it would take care of everything, instead of updating these two files?

Vlad
  • 8,038
  • 14
  • 60
  • 92
  • Checkout different build variants (types/flavors). More under [Configure your build](https://developer.android.com/studio/build/index.html) and [Configure Build Variants](https://developer.android.com/studio/build/build-variants.html). It should be able to use different modules using different gradle builds. Something like `./gradlew app:assembleModule1` and `./gradlew app:assembleModule2`. Maybe this answers your question: http://stackoverflow.com/questions/28081846/use-different-build-types-of-library-module-in-android-app-module-in-android-stu – Timo Bähr Dec 19 '16 at 08:50
  • @TimoBähr thanks, this works if you have only limited combination of modules but I'm thinking somewhat of a plugin type architecture where developers can mix and match different modules depending on what they need. I am not sure if this approach would work for this purpose.. – Vlad Dec 19 '16 at 21:20

1 Answers1

1

You can make your settings.gradle file dynamic, then the projects just need to be in a predictable path. In the future to include a new project you only need to create the folder structure and add a build.gradle file.

$ cat settings.gradle

// search for directories at the same level as the `settings.gradle` file
def moduleDirs = settingsDir.listFiles(new FileFilter() {
    @Override
    boolean accept(File pathname) {
        // if is a directory and directory contains a `build.gradle` file add to `moduleDirs` list
        return pathname.isDirectory() && pathname.listFiles(new FileFilter() {
            @Override
            boolean accept(File file) {
                return file.name == 'build.gradle'
            }
        }).size() == 1
    }
})
// now that we know all the modules create a project for each
// modules will define their own relationship (in their `build.gradle`)
// here we just declare the name and location of each
for (def moduleDir : moduleDirs) {
    include ":$moduleDir.name"
    project(":$moduleDir.name").projectDir = moduleDir
}

Not quite a single file solution however you now don't have to touch the settings.gradle again.

In the future if someone wants to make a consumer they could either rely on the jar output of the build (ie maven repo stored jars) or add their project to the file structure. From there they could choose what projects to depend on as usual in the build.gradle

projectA/build.gradle: Contains projectA && projectB but not projectC..projectZ

// ...
dependencies {
    compile project(':projectB')
}

projectC/build.gradle: Contains projectC && projectZ but projectA || projectB

// ...
dependencies {
    compile project(':projectZ')
}
JBirdVegas
  • 10,855
  • 2
  • 44
  • 50