How to nest modules in Android Studio - gradle

I am trying to build a project with the following structure. It is an app that uses a library project using another library (Google Volley).
- MainProject
|-- ModuleProject
|-- SubmoduleProject
ModuleProject/build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
}
}
apply plugin: 'android-library'
dependencies {
compile project(':SubmoduleProject')
}
ModuleProject/settings.gradle
include ':SubmoduleProject'
Android studio throws the following error:
Project with path ':SubmoduleProject' could not be found in project ':ModuleProject'
How can I build my project with nested libraries?

Your MainProject/settings.gradle should have
include 'ModuleProject', 'ModuleProject:SubmoduleProject'
and the dependency will be compile project(':ModuleProject:SubmoduleProject')

Related

How to convert a submodule to a jar and use it as a dependency rather than the project itself

My project has a two modules, an app module, and a lib module.
For my app I have the following in the app module's build.gradle file
apply plugin: 'com.android.application'
dependencies {
implementation project(':my-lib')
implementation 'com.android.support:appcompat-v7:27.1.1'
}
I would like to convert my-lib into a jar, and use the jar as the dependency rather than the module itself, so I added a libs folder in the parent folder of the src folder,
app
AndroidManifest.xml
build
src
res
libs
added the jar to libs and defined the libs folder in the build.gradle
apply plugin: 'com.android.application'
dependencies {
implementation project(':my-lib')
implementation 'com.android.support:appcompat-v7:27.1.1'
}
repositories {
flatDir {
dirs 'libs'
}
}
How can I instruct Gradle to use the jar? Is this the correct path?
Changing this
dependencies {
implementation project(':my-lib')
implementation 'com.android.support:appcompat-v7:27.1.1'
}
to this
dependencies {
api files('libs/my-lib.jar')
implementation 'com.android.support:appcompat-v7:27.1.1'
}
seems to have worked

How to use custom gradle plugin in library module project

I have a custom gradle plugin which has uploaded into jcenter, I can use it in my android project like:
root project build.gradle:
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.myproject:projectname:1.0.1'
}
app's build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.myproject.projectname'
myconfig {
......
}
It works fine. But when I use it in my android library module, It will show error message "Gradle DSL method no found:'myconfig()'"
library module's build.gradle
apply plugin: 'com.android.library'
apply plugin: 'com.myproject.projectname'
myconfig {
......
}
anyone known why?
I found the reason, in my gradle plugin I checked the project like this:
if (project.getPlugins().hasPlugin(AppPlugin)) {....}
so when I call it in library module, it can't goto the right branch.
put your jar/dependencies in a folder (suppose "libs")
then show the directory
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compile name: 'jarFile'
}
or something like:
dependencies {
compile files('libs/something_local.jar')
compile 'package_name'
}

How to setup dependencies in a multi module Android Gradle project with interdependencies?

The Question
How do I setup the dependencies of the modules in an Android Gradle project, where the modules have dependencies on each other, such that I can deploy a build of a new snapshot or release version of all modules in one go?
Project Setup
I have a project that consists of 2 modules: lib-core and lib-help, with lib-help depending on lib-core. I want to publish lib-core and lib-help seperately to Maven Central, such that the pom file of lib-help specifies the dependency on lib-core with the correct version.
The project is structured as follows:
/my-project-name
|
|--/lib-core
| |-- build.gradle
| |-- gradle.properties
|
|--/lib-help
| |-- build.gradle
| |-- gradle.properties
|
|-- build.gradle
|-- gradle.properties
|-- settings.gradle
|-- gradle-mvn-push.gradle
The project configuration files are as follows, showing only the relevant parts (by my judgement):
settings.gradle:
include ':lib-core', ':lib-help'
gradle.properties:
GROUP=com.company
VERSION=5.0.0-SNAPSHOT
gradle-mvn-push.gradle:
apply plugin: 'maven'
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
// GROUP is defined in <root>/gradle.properties
pom.groupId = GROUP
// ARTIFACT is defined in <root>/<module>/gradle.properties
pom.artifactId = ARTIFACT
// VERSION is defined in <root>/gradle.properties
pom.version = VERSION
}
}
}
}
// Contains a lot more to fill in other meta-data like project name,
// developer name, github url, javadoc, signing of the artifacts, etc, etc..
lib-core/gradle.properties:
ARTIFACT=my-lib-core
lib-core/build.gradle:
apply plugin: 'com.android.library'
// Contains more code to configure the android stuff, not relevant for this question
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
apply from: rootProject.file('gradle-mvn-push.gradle')
lib-help/gradle.properties:
ARTIFACT=my-lib-help
lib-help/build.gradle:
apply plugin: 'com.android.library'
// Contains more code to configure the android stuff, not relevant for this question
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':lib-core')
}
apply from: rootProject.file('gradle-mvn-push.gradle')
The Problem
When I run gradlew clean :lib-core:uploadArchives :lib-help:uploadArchives, everything compiles nicely and uploads are being pushed to the correct repository. In the Nexus Repository Manager I can see the artifacts for both modules with the correct name, version, signing, etc., but the dependency of lib-help on lib-core in the generated pom.xml is wrong. It uses the project name as groupId, the module name as the artifactId and an unspecified version name:
<dependency>
<groupId>my-project-name</groupId>
<artifactId>lib-core</artifactId>
<version>unspecified</version>
<scope>compile</scope>
</dependency>
Consequently, projects using lib-help as a dependency can't resolve the lib-core dependency. The correct values that should have been in lib-help's pom.xml are groupId=com.company, artifactId=my-lib-core and version=5.0.0-SNAPSHOT.
To fix this, I thought I'd use a maven dependency in lib-help, instead of a module dependency, like this:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.company:my-lib-core:' + VERSION
}
Naturally, this version does not exist before the uploadArchives command of lib-core has been executed, but gradle wants to resolve the dependencies of all modules before starting execution of any of the given commands. Thus, it can't resolve this dependency and quits with an error while configuring the gradle projects. Now, I can work around this by temporarily setting the dependency of lib-help to project(':lib-core'), then release lib-core, then adjust the dependency of lib-help to 'com.company:my-lib-core:5.0.0-SNAPSHOT', then release lib-help, but that just doesn't seem the right way. It invites human mistakes (what if I accidentally increase the version number between the to uploadArchives commands?) and it takes several manual, strictly ordered steps.
The Question (reprise)
How do I setup the dependencies of the modules in an Android Gradle project, where the modules have dependencies on each other, such that I can deploy a build of a new snapshot or release version of all modules in one go? (e.g., but not necessarily, with the command gradlew clean :lib-core:uploadArchives :lib-help:uploadArchives)
It's possible to keep the local project dependencies (compile project(':core')), if you rewrite the POM before uploading:
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
// ... other config here ...
pom.whenConfigured { pom ->
pom.dependencies.forEach { dep ->
if (dep.getVersion() == "unspecified") {
dep.setGroupId(GROUP)
dep.setVersion(VERSION_NAME)
}
}
}
}
}
}
}
Here's an example of a working project: https://github.com/hannesstruss/WindFish

Android Studio / gradle: "Could not create plugin of type 'LibraryPlugin'"

I have two modules in Android Studio.
Main is the application and Sub is a library module. Sub is referred from Main with compile project(':Sub') in the gradle script. That works when run from Android Studio. But when run from command line, gradlew says:
Could not create plugin of type 'LibraryPlugin'.
Caused by: java.lang.NoClassDefFoundError: org/gradle/api/artifacts/result/ResolvedComponentResult
This is the important parts in Main's build.gradle file:
apply plugin: 'android'
buildscript {
repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
}
}
repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
task wrapper(type: org.gradle.api.tasks.wrapper.Wrapper) {
gradleVersion = '1.11'
}
android {
buildToolsVersion '19.0.3'
}
dependencies {
compile 'com.android.support:support-v4:13.0.+'
compile project (':Sub')
}
The Sub gradle file is more or less identical, but has
apply plugin: 'android-library'
instead of 'android'
I have tried with gradle 1.9 and 1.10, but same result.
Anyone knows how to solve this?
Verify that your dependencies contains classpath 'com.android.tools.build:gradle:0.9.+' in each gradle.build file (or just put it in the base one and not declare it in the others). Update gradle/wrapper/gradle-wrapper.properties to point to gradle 1.11:
distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip
If you have any other instances of the gradle-wrapper (such as if you originally made the library project on its own and later added an example app), verify that all instances are updated to point to the same version (each gradle-wrapper.properties file).

How to properly setup Gradle in Android Studio for ActionBarSherlock?

So I'm struggling to setup a very simple Project in Android Studio v0.2 with Gradle v1.6.
I want to create a simple app that uses ActionBarSherlock, so I created a Project in Android Studio.
In the same root folder as the Project is created, I have downloaded the latest ABS.
So here's my structure:
|ABSAppProject
|..settings.gradle
|..build.gradle
|--ABSApp
|....build.gradle
|actionbarsherlock
|..build.gradle
In the root settings.gradle, I have:
include ':ABSApp'
include 'actionbarsherlock'
project(':actionbarsherlock').projectDir=new File('actionbarsherlock')
In the actionbarsherlock/build.gradle I have:
apply plugin: 'android-library'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
dependencies {
compile 'com.google.android:support-v4:r7'
}
android {
compileSdkVersion 14
buildToolsVersion '17'
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
}
}
}
And, finally in, the ABSApp/build.gradle, I have:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
dependencies {
compile 'com.android.support:support-v4:r7'
compile project (':actionbarsherlock')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 9
targetSdkVersion 16
}
}
The root build.gradle is empty.
When building, (using gradle build --info) I get:
Starting Build
Settings evaluated using settings file '/Users/m/Documents/Projects/ABSAppProject/settings.gradle'.
Projects loaded. Root project using build file '/Users/ma/Documents/Projects/ABSAppProject/build.gradle'.
Included projects: [root project 'ABSAppProject', project ':ABSApp', project ':actionbarsherlock']
Evaluating root project 'ABSAppProject' using build file '/Users/m/Documents/Projects/ABSAppProject/build.gradle'.
Evaluating project ':ABSApp' using build file '/Users/m/Documents/Projects/ABSAppProject/ABSApp/build.gradle'.
Evaluating project ':actionbarsherlock' using empty build file.
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':ABSApp'.
> Failed to notify project evaluation listener.
> Configuration with name 'default' not found.
Building the ABS library alone using Gradle seems to work ok, so that gradle.build file is probably ok.
What am I doing wrong?
There is no need for downloading ABS separately. Gradle supports Android's new .aar format which makes using library projects easier. Just add this (or whatever version it is currently) to dependencies section in build.gradle of your project:
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0#aar'
and let Gradle handle the rest.
The entry for actionbarsherlock in settings.gradle should be
include '..:actionbarsherlock'
you should not need project(':actionbarsherlock').projectDir=new File('actionbarsherlock')

Resources