5

I have an Android Studio project which has 3 modules in it. A, B, C. A depends on C and B depends on C. I'm trying to speed up build times, and i realised that every time i execute assembleRelease/assembeDebug task it builds ALL modules. Every time i build module A should only build A and C, because B has no dependency in that task, right? How can i avoid module B to build every time i build module A?

Module A dependencies:

dependencies {
    compile project(path: ':c', configuration: 'release')
    provided files('libs/some-lib.jar')
}

Module B dependencies:

dependencies {
    compile project(path: ':c', configuration: 'debug')
}

Module C dependencies:

dependencies {
    compile files('libs/other-lib.jar')
}
Dave Thomas
  • 3,667
  • 2
  • 33
  • 41
  • How are you running the tasks? Via the command line, or via the Gradle dialog in Android Studio? –  Sep 15 '17 at 20:23
  • I was running tasks from gradle dialog.. now im running tasks from command line and the build times decreased a lot.. apparently gradle dialog builds all modules no matter what you are trying to build – Nicolas Lorusso Sep 18 '17 at 14:30
  • What is happening is that (if you look carefully) running a submodule task from Android Studio is actually invoking the task from the root of the project. Since the root usually contains all refs, the configured build tree it makes contains all modules. If you start a second instance/window of Android Studio running a submodule task will just make a build tree based on that module and it's dependencies. This is easy to see in the Gradle log. –  Oct 05 '17 at 17:06

3 Answers3

9

I've made it clear in comments that I feel that hacking settings.gradle to remove modules is a Bad Idea.

So, if you can't run Android Studio with two or more projects open, or you don't want to invoke Gradle on a command line, or you just want to disable some modules because they are not of interest to you, there actually is a supported way to do this. (At least in recent releases of Android Studio like 3.2.x.)

  1. Right-click on the top-level Project or any module in the Project view
  2. Select Load/Unload Modules...
  3. Unload the modules you don't want to be active

Since this only ever changes your local project and can never be committed by accident, this is a safe way to reduce module overhead safely. I think it even does a sync for you so you don't have to force a sync by hand.

1

Simply removing the include statement of the related module (B in this case) within the root settings.gradle file should stop Android Studio from building B as it will exclude it from the overall Gradle project. The module will stay intact, however if you plan on modifying any code in it then re-adding the include statement is necessary. Also note that modifying the settings.gradle file will require a Gradle Sync for Android Studio to perform properly.

ahasbini
  • 6,761
  • 2
  • 29
  • 45
  • This is like saying you don't want Module B to be part of the project, which is probably not what we want to do here. –  Sep 18 '17 at 15:09
  • 1
    It really depends on how things are structured actually and this is kind of opinionated. For me if module directory is within the project root, I for one wouldn't consider it being removed from the project even if the ```include``` statement is removed, its still there but its not active, and hence will result with less with less build which is the core point of the OP – ahasbini Sep 18 '17 at 15:18
  • Yes, but Android Studio, at least in 2.x, _considers it removed_. It will even ask you if you want to remove it from the list of modules, and it will be rendered in normal font instead of bold in the UI. Even if you do not "remove" it, but keep it in the list of modules but unattached to the main project there will be all sorts of issues. Gradle from the command line will probably still work, but syncing and other UI activities in Android Studio will never see that module. Further, in a team setting this file is shared, and tweaking it will lead to all sorts of unnecessary confusion. –  Sep 18 '17 at 15:56
  • Oh no i do it all the time, never had any issues with it and it does not cause any issues with gradle or in android studio. The idea is actually for android studio not to act upon the module or build it at all since I'm not using it, it simply stops building it with gradle and in my team we are totally fine with it. Again like i said that this is totally opinionated and there's no single right side to it, they could be both right, or they could be both wrong. Personally I dont see it bothering, the code is still there if i ever needed to see something and i can still see it in android studio. – ahasbini Sep 18 '17 at 16:21
  • The notion that you have to re-add the module to the IDE every time you want to maintain it sounds like an egregious hack. Especially when the reason for the reported problem is because of a bug in Android Studio. Yes, it is my informed opinion that what you are doing is a hack, and I would specifically recommend people to not follow this advice. Instead of doing this, make the module a library and publish it. Because there is really no reason to have the _source_ in the same project then. –  Sep 18 '17 at 17:20
  • Well it's a hack that Android Studio can easily complete without any errors, makes it more of a feature for a good reason in my opinion. I don't believe that the bug that you've associated with problem is really the true cause, hence the reason why I've posted a different answer. I've been developing android projects with lots of modules in it, pretty much ended with short and reasonable build times, that's of course because there is gradle caching that doesn't rebuild unmodified modules, which Android Studio leverages nicely and is improving over the time with its plugin. – ahasbini Sep 19 '17 at 05:01
  • The bug I posted is the root of this problem if the problem goes away when running Gradle from the command line and the problem persists when running the tasks from the Gradle dialog. If you look carefully you will see that the top-level Gradle is being invoked, not the submodule Gradle as expected. And, BTW, just because something works now doesn't mean it isn't a hack. It's also a hack to run two instances of AS, which also fixes the problem I reported. Seriously, just for future visitors: don't hack the settings.gradle like this. It is bad advice. This is why I have to down-vote. –  Oct 05 '17 at 17:03
0

There is a bug in Android Studio where if you use the Gradle projects dialog to run tasks, those tasks will be run in the root context. That is, if you look carefully, even submodule tasks are run as if you ran the same task at the root level.

Solutions:

  1. Use the command line Gradle or Gradle wrapper.
  2. Always run two instances of Android Studio (i.e., have multiple projects open)