I try to specify two different sourcesets of a gradle library and add a sourceset specific dependency in a project.
The idea is to do something like this:
The library build.gradle file:
apply plugin: 'com.android.library'
android {
...
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java {
srcDir 'src'
}
res {
srcDir 'res'
}
}
exclude_fr_it{
manifest.srcFile 'AndroidManifest.xml'
java {
srcDir 'src'
}
res {
srcDir 'res'
exclude 'res/values/values-fr'
exclude 'res/values/values-it'
}
}
}
...
}
...
In the Project A, I want to include the main sourceset:
dependencies {
compile project(':explore_layout')
}
In the Project B, I want to include the build that use sourceset exclude_fr_it.
dependencies {
compile project(':explore_layout') library 'exclude_fr_it'
}
I tried to understand the documentation. But I don't see how this can be done...
Question 1
Doc
Question 2
This is not a direct answer to the sourceSets question. But you may not need to use the sourceSets feature at all.
If you simply want your app to include a subset of the resources in your custom android library, you can accomplish that with a configuration block in your app's build.gradle. (In fact, the library does not need those special configuration blocks for the 'main' and 'exclude_fr_it' sourceSets at all.)
This is possible because of the 'resConfigs' property.
In particular, suppose your library has resource configurations for three languages: 'en', 'fr', and 'it'.
Then, in project A, which includes all of the languages from the library, you simply use this in build.gradle:
dependencies {
compile project(':explore_layout')
}
But, in project B, which you want to exclude the custom library's 'fr' and 'it' resources, you use the 'resConfigs' property within a configuration closure to include only a subset of resources like this:
dependencies {
compile project(':explore_layout') {
android {
defaultConfig {
resConfigs 'en'
}
}
}
}
I have achieved this using distribution to mavenLocal of a specific sources specification. I have a library project that has some java.awt code that I want to omit so I can include the project as dependency to an android project (which doesnt support java.awt)
In your library you will have something like this:
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'maven-publish'
sourceSets {
main {
java {
srcDirs = [ 'src' ]
}
}
// android source set excludes portion of source that
// references java.awt
android {
java {
srcDirs = [ 'src' ]
excludes = ['**/skunkworks/**', '**/awt/**']
}
}
}
// this task compiles sources defined by custom sourceSet 'android'
task androidJar(type: Jar) {
from sourceSets.find {'android'}.output
}
publishing {
publications {
myLibrary(MavenPublication) {
groupId = 'foo.bar'
artifactId = 'mylib-android'
version = '1.0'
artifact androidJar
}
}
}
Then use the tasks->publishing->publishToMavenLocal target to compile the custom jar to your ~/.m2/repository.
Now in the android project I reference like this:
repositories {
mavenLocal()
}
dependencies {
implementation 'foo.bar:mylib-android:1.0'
}
I'm trying to generate .java files from the .proto files I have stored under my SRC folder in Android studio. I put the below code in my gradle file by it doesn't seem to work
apply plugin: 'com.squareup.wire'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.squareup.wire:wire-maven-plugin:2.1.1'
}
}
There is a gradle plugin for wire here: https://github.com/square/wire-gradle-plugin. However, it seems like it's not quite ready for primetime yet. I had some trouble getting it working.
But, here's a way to do it that automates generation of java code from the *.proto files using the wire compiler directly and a simple gradle task. I've provided a snippet below with the modifications to your build.gradle. Change the protoPath and wireGeneratedPath based on your source layout.
def protoPath = 'src/proto'
def wireGeneratedPath = 'build/generated/source/wire'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.squareup.wire:wire-compiler:2.2.0'
}
}
android {
sourceSets {
main {
java {
include wireGeneratedPath
}
}
}
}
dependencies {
compile 'com.squareup.wire:wire-runtime:2.2.0'
// Leave this out if you're not doing integration testing...
androidTestCompile 'com.squareup.wire:wire-runtime:2.2.0'
}
// This handles the protocol buffer generation with wire
task generateWireClasses {
description = 'Generate Java classes from protocol buffer (.proto) schema files for use with squareup\'s wire library'
delete(wireGeneratedPath)
fileTree(dir: protoPath, include: '**/*.proto').each { File file ->
doLast {
javaexec {
main = 'com.squareup.wire.WireCompiler'
classpath = buildscript.configurations.classpath
args = ["--proto_path=${protoPath}", "--java_out=${wireGeneratedPath}", "${file}"]
}
}
}
}
preBuild.dependsOn generateWireClasses
So instead of using a gradle plugin I just ended up using the square wire compiler jar. Here are the steps.
Download compiler-jar-with-dependencies from http://search.maven.org/#artifactdetails%7Ccom.squareup.wire%7Cwire-compiler%7C2.1.1%7Cjar
Put jar file into root directory of android app
Go to the directory and paste this command
java -jar wire-compiler-2.1.1-jar-with-dependencies.jar --proto_path=directory-of-protofile --java_out=app/src/main/java/ name-of-file.proto
Should work. Make sure to replace the directory-of-protofile and name-of-file with whatever you have.
I'm aware of this question: Adding local .aar files to my gradle build but the solution does not work for me.
I tried adding this statement to the top level of my build.gradle file:
repositories {
mavenCentral()
flatDir {
dirs 'libs'
}
}
I've also put the slidingmenu.aar file into /libs and referenced it in the dependencies section: compile 'com.slidingmenu.lib:slidingmenu:1.0.0#aar' but it did not work at all.
I tried compile files('libs/slidingmenu.aar') as well but with no luck.
What am I missing? Any ideas?
P.S. Android Studio 0.8.2
Building upon Josiah's answer, here's how I got it to work.
Following his instructions (under edit) (File -> New-> New Module -> Import .JAR/.AAR) and import your .AAR.
Then in your project build.gradle (not the top level one, the one under 'app') add the following (in the dependencies section):
dependencies {
compile project(':Name-Of-Your-Project')
}
Note Name-Of-Your-Project should match the name of the folder that was added after you imported the AAR file (at the same level as app/.idea under the top most level folder). Or to put it another way...
MyApplication
.idea
app
build.gradle (here's where to add compile project(':ProjectName') to dependency section)
ProjectName (added automatically after importing, matching the name of your aar file)
build
gradle
etc
This worked for me running Android Studio 0.8.0. Don't forget to synchronize gradle (using toolbar button or in File->Synchronize) after you do this.
(Thanks to Josiah for getting me going in the right direction)
(Note: prior to this I tried adding it to the libs folder, trying to manipulate the top level build.gradle and the app level build.gradle, but none of that worked for my aars files--jar's will work fine, but not the aar files)
Update : As #amram99 mentioned, the issue has been fixed as of the release of Android Studio v1.3.
Tested and verified with below specifications
Android Studio v1.3
gradle plugin v1.2.3
Gradle v2.4
What works now
Now you can import a local aar file via the File>New>New
Module>Import .JAR/.AAR Package option in Android Studio v1.3
However the below answer holds true and effective irrespective of the Android Studio changes as this is based of gradle scripting.
Old Answer :
In a recent update the people at android broke the inclusion of local aar files via the Android Studio's add new module menu option.
Check the Issue listed here.
Irrespective of anything that goes in and out of IDE's feature list , the below method works when it comes to working with local aar files.(Tested it today):
Put the .aar file in the libs directory (create it if needed), then, add the following code:
In the module build.gradle:
dependencies {
compile(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
}
In the project build.gradle:
repositories{
flatDir{
dirs 'libs'
}
}
Edit:
The correct way (currently) to use a local AAR file as a build dependency is to use the module import wizard (File | New Module | Import .JAR or .AAR package) which will automatically add the .aar as a library module in your project.
Old Answer
Try this:
allprojects {
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
}
...
compile(name:'slidingmenu', ext:'aar')
I got this working on Android Studio 2.1. I have a module called "Native_Ads" which is shared across multiple projects.
First, I created a directory in my Native_ads module with the name 'aars' and then put the aar file in there.
Directory structure:
libs/
aars/ <-- newly created
src/
build.gradle
etc
Then, the other changes:
Top level Gradle file:
allprojects {
repositories {
jcenter()
// For module with aar file in it
flatDir {
dirs project(':Native_Ads').file('aars')
}
}
}
App module's build.gradle file:
- no changes
Settings.gradle file (to include the module):
include ':app'
include 'Native_Ads'
project(':Native_Ads').projectDir = new File(rootProject.projectDir, '../path/to/Native_Ads')
Gradle file for the Native_Ads module:
repositories {
jcenter()
flatDir {
dirs 'aars'
}
}
dependencies {
compile(name:'aar_file_name_without_aar_extension', ext:'aar')
}
That's it. Clean and build.
This solution is working with Android Studio 4.0.1.
Apart from creating a new module as suggested in above solution, you can try this solution.
If you have multiple modules in your application and want to add aar to just one of the module then this solution come handy.
In your root project build.gradle
add
repositories {
flatDir {
dirs 'libs'
}}
Then in the module where you want to add the .aar file locally. simply add below lines of code.
dependencies {
api fileTree(include: ['*.aar'], dir: 'libs')
implementation files('libs/<yourAarName>.aar')
}
Happy Coding :)
The easiest way now is to add it as a module
This will create a new module containing the aar file, so you just need to include that module as a dependency afterwards
This is my structure, and how I solve this:
MyProject/app/libs/mylib-1.0.0.aar
MyProject/app/myModulesFolder/myLibXYZ
On build.gradle
from Project/app/myModulesFolder/myLibXYZ
I have put this:
repositories {
flatDir {
dirs 'libs', '../../libs'
}
}
compile (name: 'mylib-1.0.0', ext: 'aar')
Done and working fine, my submodule XYZ depends on somelibrary from main module.
You can do it this way. It needs to go in the maven format:
repositories {
maven { url uri('folderName')}
}
And then your AAR needs to go in a folder structure for a group id "com.example":
folderName/
com/
example/
verion/
myaar-version.aar
Then reference as a dependency:
compile 'com.example:myaar:version#aar'
Where version is the version of your aar file (ie, 3.0, etc)
In my case, I just put the AAR file in libs, and add
dependencies {
...
api fileTree(dir: 'libs', include: ['*.aar'])
...
}
in build.gradle and it works. I think it is similar with default generated dependency:
implementation fileTree(dir: 'libs', include: ['*.jar'])
In my case the none of the answers above worked! since I had different productFlavors just adding
repositories {
flatDir {
dirs 'libs'
}
}
did not work! I ended up with specifying exact location of libs directory:
repositories{
flatDir{
dirs 'src/main/libs'
}
}
Guess one should introduce flatDirs like this when there's different productFlavors in build.gradle
For anyone who has this problem as of Android Studio 1.4, I got it to work by creating a module within the project that contains 2 things.
build.gradle with the following contents:
configurations.create("default")
artifacts.add("default", file('facebook-android-sdk-4.7.0.aar'))
the aar file (in this example 'facebook-android-sdk-4.7.0.aar')
Then include the new library as a module dependency. Now you can use a built aar without including the sources within the project.
Credit to Facebook for this hack. I found the solution while integrating the Android SDK into a project.
If you already use Kotlin Gradle DSL, the alternative to using it this way:
Here's my project structure
|-root
|----- app
|--------- libs // I choose to store the aar here
|-------------- my-libs-01.aar
|-------------- my-libs-02.jar
|--------- build.gradle.kts // app module gradle
|----- common-libs // another aar folder/directory
|----------------- common-libs-01.aar
|----------------- common-libs-02.jar
|----- build.gradle.kts // root gradle
My app/build.gradle.kts
Using simple approach with fileTree
// android related config above omitted...
dependencies {
// you can do this to include everything in the both directory
// Inside ./root/common-libs & ./root/app/libs
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
implementation(fileTree(mapOf("dir" to "../common-libs", "include" to listOf("*.jar", "*.aar"))))
}
Using same approach like fetching from local / remote maven repository with flatDirs
// android related config above omitted...
repositories {
flatDir {
dirs = mutableSetOf(File("libs"), File("../common-libs")
}
}
dependencies {
implementation(group = "", name = "my-libs-01", ext = "aar")
implementation(group = "", name = "my-libs-02", ext = "jar")
implementation(group = "", name = "common-libs-01", ext = "aar")
implementation(group = "", name = "common-libs-02", ext = "jar")
}
The group was needed, due to its mandatory (not optional/has default value) in kotlin implementation, see below:
// Filename: ReleaseImplementationConfigurationAccessors.kt
package org.gradle.kotlin.dsl
fun DependencyHandler.`releaseImplementation`(
group: String,
name: String,
version: String? = null,
configuration: String? = null,
classifier: String? = null,
ext: String? = null,
dependencyConfiguration: Action<ExternalModuleDependency>? = null
)
Disclaimer:
The difference using no.1 & flatDirs no.2 approach, I still don't know much, you might want to edit/comment to this answer.
References:
https://stackoverflow.com/a/56828958/3763032
https://github.com/gradle/gradle/issues/9272
This line includes all aar and jar files from libs folder:
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs/')
Add below in app gradle file
implementation project(path: ':project name')
Followed the steps in http://developer.android.com/samples/index.html, I imported repeatingAlarm (http://developer.android.com/samples/repeatingAlarm/project.html) project into Android Studio. Unfortunately, I get an error below:
Failed to refresh Gradle project 'repeatingAlarm'
The project is using an unsupported version of the Android Gradle plug-in (0.6.3).
Fix plug-in version and re-import project
Quick Fix Failed
Unable to find any references to the Android Gradle plug-in in build.gradle files.
Please click the link to perform a textual search and then update the build files manually.
Here below is the build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android'
dependencies {
// Add the support lib that is appropriate for SDK 4
compile "com.android.support:support-v4:18.0.+"
}
// The sample build uses multiple directories to
// keep boilerplate and common code separate from
// the main sample code.
List<String> dirs = [
'main', // main sample code; look here for the interesting stuff.
'common', // components that are reused by multiple samples
'template'] // boilerplate code that is generated by the sample template process
android {
compileSdkVersion 19
buildToolsVersion "18.0.1"
sourceSets {
main {
dirs.each { dir ->
java.srcDirs "src/${dir}/java"
res.srcDirs "src/${dir}/res"
}
}
instrumentTest.setRoot('tests')
instrumentTest.java.srcDirs = ['tests/src']
}
}
And here the IDE told me an error like this:
What am I supposed to do?
change buildToolsVersion "18.0.1" to latest version like "20.0.1", it will work :)
This query is continuation to my previous question as i did not get answer so i am requesting here. My previous question can be found here (android - gradle multiproject include and exclude libraries)
With productFlavors, one can avoid include and exclude library projects to main project.
In my case,
ProjectA----- MainProject,
LibA ---- Library project,
LibB ---- Library project,
....
LibA classes are used in ProjectA.
LibB classes are not used any where. Its just a library but required as part of ProjectA.apk(Mentioned only in ProjectA manifest file)
After "gradle build", in build/classes/flavor/debug or release/packageName/.. only LibA classes are there. LibB classes are not there in build/classes/.. path and LibB functionality is not working. (Note: The same is working fine with eclipse build)
LibB classes are getting included if by importing LibB classes in ProjectA but LibB is like plug and play type library and not required for all the time.
LibB build.gradle file is as follows:
buildscript {
repositories {mavenCentral()}
dependencies {
classpath 'com.android.tools.build:gradle:0.3'}
}
apply plugin: 'android-library'
android {
compileSdkVersion 14
sourceSets {
main {
manifest {srcFile 'AndroidManifest.xml'}
java {srcDir 'src'}
res {srcDir 'res'}
assets {srcDir 'assets'}
resources {srcDir 'src'}
jni {srcDir 'jni'}
}
}
task configureRelease << {
proguard.enabled = true
}
}
How to get include LibB? Please guide me resolving this issue.
Thanks in advance
You need add dependencies node...
dependencies {
compile project(':LibB')
}
android {
XXX
}