I could use a little help understanding the concepts behind Gradle(plugin v 0.7) in the context of Android Studio 0.4.0. I have not used Gradle before and it’s causing me nothing but problems. I’m not seeing its purpose/benefit because I don’t know enough about it.
Some specific questions I have
What are these dependencies? I’m making a simple app with a
navigation drawer, targeted to API 11+ where it should be natively
supported. What dependencies could I be using?
What is a Gradle wrapper? What changes, if any, does it make to the completed application?
Why does Gradle need to be online constantly? I don’t have
internet access on my personal laptop when I’m at work. It’s gotten
to the point that I can’t run or test my app because Gradle can’t
resolve some resource without internet access.
Why is it important that Gradle uses Groovy? I have searched
around the internet and that tends to be something people like about
Gradle but they don’t usually explain why Groovy is important or
what it does for an Android app.
Sometimes it’s tough as an intermediate programmer as information tends to be overly simple or overly complex. Aside from my specific questions, any additional information you can provide would be useful. I’m not looking to debate the pros and cons of Gradle vs other tools that may do the same thing, I’d just like to know more about Gradle and its use so I can make informed decisions.
Some of your questions are general in that they speak to why build tools are a good thing as a general matter. Others get to Gradle specifically. I will try to address both categories as succinctly as possible while trying to avoid others’ nitpicking terminology.
Build tools like Maven, Gradle, SBT, Leiningen, etc. help to automate tasks that we would otherwise have to manually perform or “manually automate.” I use the latter to describe what I used to do with Ant–writing custom tasks to compile, run, generate Javadoc, etc. so the tasks could be automated for the future. By conforming to conventions originally defined by Maven and adopted by the others subsequently (like putting your source in src/main/java), this becomes possible. If I follow the conventions, the build tool can compile, run, generate Javadoc, test, and everything else with minimal extra work.
Now to your questions (in order):
- Another critical function of build tools is to reduce “jar hell” by managing dependencies in a consistent way across builds. I just specify which version of Apache Commons or Google Guava or Spring or Jackson I want (or even range of versions) and the build tool will download them and put them somewhere so they can be in the classpath and in the build if applicable (like a war file). I can also define scopes–like I want this dependency to be available at compile time but this other one only at runtime. Do I need to provide it explicitly, or will it be available? Stuff like that.
- This is Gradle specific. As described here, the Gradle wrapper helps teams run Gradle without having to manually install Gradle while also maintaining consistency. Everyone uses the same version. Once you set it up, you never have to worry about it, and all the Gradle tasks you want to use are available via the wrapper, so you need not even care that it’s there. You can choose to install Gradle directly and run it directly, but I rarely see the point.
- This is general. I mentioned dependency management earlier. In order to fetch these dependencies, the build tool needs to get online where they are available from Maven Central or a bunch of third-party repositories. Another Maven innovation adopted by the others is repository management, so compiled artifacts are published to a repository according to convention so other projects can use them. Usually, you don’t care about that. You just tell the tool you need a certain dependency, and it knows how to grab it because everyone follows the conventions. In situations where you are without internet access (something I am quite familiar with), your options are to just grab all dependencies when you are online and then optionally to set up a local Maven repository like Nexus or Artifactory to publish those artifacts to. Then you tell your build tool to look there as well as Maven Central, etc.
- Maven is configured with XML, and that seemed really cool at the time. But there are two consequences. One is the configuration becomes very verbose. Another is that it gets hard to do custom things. You have to do everything declaratively in XML, which many find to be a pain. You configure plugins in XML, or you write your own and wrap it in a way Maven can understand and can be configured in XML. It is a lot easier and more powerful to do custom build stuff in code. Gradle chose Groovy for this because Groovy makes for nice DSL’s and is really easy to learn for Java developers coming from Maven. SBT chose Scala and Leiningen chose Clojure because those build tools target those languages/platforms, so a Scala developer, for example, doesn’t have to learn anything new to use SBT besides the DSL. But the broader point is that relying on code rather than XML has a lot of benefit.
Hope that helps.
What are these dependencies?
There are so many cool libraries you might decide to use. And a lot of these libraries are supporting the integration with gradle now. So no more importing the project and hosting it yourself. Everything is hosted on mavencentral. You still need the support library for example, even if you decide to target API 11+.
What is a Gradle wrapper?
A gradle wrapper is an awesome tool, if you’re working in a team, or especially on an open source project. You don’t need to have gradle installed. The gradle wrapper will download and cache all its dependencies on the first run. So all the developers on your team can build the project really quickly.
Why does Gradle need to be online constantly?
Because the dependencies need to be synced. You’re in luck, if you are using Android Studio though.
The latest version supports a “gradle offline mode”.
From the release notes:
Studio now supports Gradle Offline mode. This is useful if you find
yourself without a network connection, and your dependencies are using
the plus-syntax to pick up the latest available version. In that case,
Gradle will once per day (by default) connect to the artifact
repository to see if there is a more recent version. If that network
connection fails, the build fails. If you don’t have a network
connection, this is problematic. You can now open the Compiler >
Gradle options and enable Offline mode, which will tell Gradle to
ignore update-to-date checks:
Why is it important that Gradle uses Groovy?
You write gradle plugins in Groovy. And all your gradle tasks in build.gradle as well.
Caution: I’m not an expert in gradle. In fact a relatively new user as well.
I understand what everyone states as far as why the online portion of Gradle is necessary, but for those of us behind firewalls at work, or when we might be working offline, it really puts a burden on us to have to go online at least once to be able to compile in offline mode.
I just don’t understand why this requirement is placed on the project. What if I’m starting an entirely new project in Android Studio that I want to test a concept with? I can’t do it unless I’m online at least once. What if I don’t have access to internet at that time and want to do this? What then?
Seems like an unnecessary requirement that burdens the developer with unnecessary issues that could be avoided. Again, I understand the reason behind it, but still, to force a requirement of at least compiling once online in order to use offline seems a little ridiculous.
I want to use Gradle, but at this point in time, it’s something we can’t even use at work due to the online requirement. I’ll have to work with our security department to determine what holes to punch in our firewall in order to allow this through as well as setting up our proxy correctly to allow it.
So, at this time, I cannot recommend Gradle for use at my place of employment which means we also will continue using Eclipse for Android development as opposed to Android Studio. Seems like a limiting requirement that doesn’t seem necessary.
Let’s assume, that understanding of the following points serves as aggreeable basis:
What are classes, interfaces, APIs, packages, modules and libraries.
What are module dependencies and what means “dependency management”.
A complexity of modern applications. Even if you do a simple “Hello, world” app (would it be a desktop application or web-application), it should include a dozen (if not a hundred) of various libraries. All these libraries provide infrastructure to your app, but many of them are not directly related to it’s logic.
If your app is not “Hello, world”, then hiding it’s complexity (by proper modularization) and automating it’s assembly and testing (by use of proper build tools) becomes crucial to success.
With this understanding in mind (and taking into account precious considerations, listed by dear colleagues above) it makes sense to start talking gradle, ant, ivy and maven.