maven-publish multi-project artifacts dependencies - android

I have been searching for an answer to my question, but I found none.
I built an android project with many modules. The modules should be published in a repository (at first in the local maven repository).
I've done a demo project with two simple projects pr1, pr2. Now I've added to pr2 the dependency for pr1.
compile ('de.test:project1:1.0.0')
After that, I can publish both artifacts.
Now, when I change the name from pr2 to aPr2, the dependency can not be resolved from in aPr2, because the jar file does not exist. The problem is that aPr2 is built before pr1.
How can I tell Gradle to build it in the correct order?
This is my Gradle file from one of the projects. Pr1 is similar, without dependency.
plugins {
id 'java'
id 'maven-publish'
}
dependencies {
// compile project(':project1')
compile ('de.test:project1:1.0.0')
testCompile 'junit:junit:4.12'
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
publishing {
publications {
publish(MavenPublication) {
groupId 'de.test'
artifactId 'project2'
version '1.0.0'
from components.java
}
}
}

You need to modify your project configuration.
When you use components.java, the maven-publish plugin will set the groupId, artifactId and version from Gradle project configuration.
The default artifactId has been set with the name of the project (default: folder name). It is read-only, but you can override it. Create a settings.gradle file in subproject folder and set the module name:
rootProject.name = 'project1'
Write these lines into build.gradle file in root project dir for setup groupId and version for all project.
allprojects {
group 'de.test'
version '1.0.0'
}
If you setup everything correctly, you can remove comment from compile project(':project1')
You can build the project and you can publish your pom file with de.test:project:1.0.0 dependency.

Related

Error building Android library: Direct local .aar file dependencies are not supported

We recently upgraded to Android Gradle Plugin 4.0.0-beta03. We are now seeing this error when building one of our library modules
$ ./gradlew library_module:assemble
Execution failed for task ':library_module:bundleDebugAar'.
> Direct local .aar file dependencies are not supported when building an AAR.
The resulting AAR would be broken because the classes and Android resources from any local .aar
file dependencies would not be packaged in the resulting AAR. Previous versions of the Android
Gradle Plugin produce broken AARs in this case too (despite not throwing this error). The
following direct local .aar file dependencies of the :library_module project caused this error:
______.aar
I can see this was added to AGP a few months ago. But they provide no further info on why.
So.
What was the problem? Any more info? I can't find a single bug report anywhere.
How exactly can I fix this? Is this saying that I can't build one .aar that depends on other local .aars? What if this local aar was instead hosted on Maven Central or another remote repo? Why would that make a difference?
I recently encountered the same issue, the fix was to remove the library from libs/ and import it using File -> New -> New Module -> Import .JAR/.AAR Package, then referencing it in the library module build.gradle file:
dependencies {
implementation project(":imported_aar_module")
}
If you are on a newer Android Studio version (4.0.0+), this option is not available. Instead you have to do it manually.
Create a new directory and put the following content into the build.gradle file withing the new directory:
configurations.maybeCreate("default")
artifacts.add("default", file('[nameOfTheAar].aar'))
Place the aar into this new directoy. Next to the build.gradle file.
Add the new created Gradle project to the settings.gradle file:
include(":pathToTheCreatedDirectory")
Include the project in your library where you want to use the aar:
implementation project(":pathToTheCreatedDirectory", configuration = "default")
I want to call out #StefMa's comment on this question which was incredible simple and solved this issue for me, but it's buried among many other comments on this thread and is easily missed.
The 'correct' answer on this thread no longer works because it's not possible to import AARs in Android Studio anymore as referred to in that answer. But, the solution referred to in StefMa's comment linking to this GitHub post does, and it works perfectly.
Long story short - put your AAR into a separate module.
There's no need to muck around with creating lib directories, just follow these directions -
Create a new directory in your project's root directory. The image below shows two of them - spotify-app-remote and spotify-auth, but one is sufficient. Within that, put your AAR in, and create a new build.gradle file.
Within the build.gradle file, add the following, replacing the aar filename with the name of your AAR file -
configurations.maybeCreate("default")
artifacts.add("default", file('spotify-app-remote-release-0.7.1.aar'))
Add this to your settings.gradle file, substituting the name of the directory you created
include ':spotify-app-remote'
Include your new module in the module you wish to use the AAR. eg, if you want to use it within your app module, open app's build.gradle and add
api project(':spotify-app-remote')
within your dependencies { } block, obviously again substituting spotify-app-remote with whatever the name of your module is.
When building an Android library that depends on other Android libraries (i.e., aar files), you will get the following error message if you include the aar files as dependencies in the project:
Direct local .aar file dependencies are not supported when building an AAR. The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR. Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error).
As the above message states, when you build an Android library project, any aar it depends on is not packaged. If you built this way prior to AGP (Android Gradle Plugin) 4, you probably noticed that you had to include the aar dependencies on the project consuming your library.
You can compile your Android library project by specifying that the aar dependencies are compileOnly. See this for more info on when to use compileOnly.
So just add the following to your app build.gradle file:
compileOnly files('libs/some-library.aar')
Note that if you do this you will have to include the aar dependencies on the application project that consumes your library.
Alternatively, you can create a module that imports your aar dependency as #Sandi mentioned in the answer above.
Another way is to publish your aar dependencies to a maven repository and then add them to your library project like this:
implementation 'mylibrarygroup:mylibraryartifact:version-x.y.z#aar'
In my experience, when Gradle Plugin version is 4.2.2+ and Gradle version is 7.1+, as in #Luis's answer 'compileOnly' works.
compileOnly files('libs/your_library_name.aar')
It didn't work when the Gradle versions were lower.
Getting same error when use this code.
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.aar'], dir: 'libs')
Replace your code with following.
Open the top level ‘build.gradle’ file and add.
repositories {
flatDir {
dirs('/src/main/libs')
}
}
Then in your project’s build.gradle add the following.
api(name:'aar_module_name', ext:'aar')
There are some changes now, You need to add your AAR or JAR as a dependency
1.) First, Navigate to File > Project Structure
[Reference Image 1]
2.) Then go to Dependencies > Declared Dependencies tab, click and select JAR/AAR Dependency in the dropdown
[Reference Image 2]
3.)In the Add Jar/Aar Dependency dialog, first enter the path to your .aar or .jar file, then select the configuration to which the dependency applies. If the library should be available to all configurations, select the "implementation" configuration.
[Reference Image 3]
4.) Click OK then Apply > OK.
You are good to go.
I had the same issue, in the sense I wanted to encapsulate a library dependency into a module. However this library dependency had a bunch of aars and creating separate module each of them is just clutter, and can't even find that option in the new studio.
To resolve it I published the aar-s into my local maven, before starting the build process.
So my encapsulating module's build.gradle looked like this:
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'maven-publish'
}
//..
parent.allprojects { // for some reason simply repositories didn't work
repositories {
mavenLocal()
}
}
//...
publishing {
publications {
barOne(MavenPublication) {
groupId 'foo-aar-dependency'
artifactId 'bar1'
version '1.0'
artifact("$libsDirName/bar1.aar")
}
barTwo(MavenPublication) {
groupId 'foo-aar-dependency'
artifactId 'bar2'
version '1.0'
artifact("$libsDirName/bar2.aar")
}
barThree(MavenPublication) {
groupId 'foo-aar-dependency'
artifactId 'bar3'
version '1.0'
artifact("$libsDirName/bar3.aar")
}
// and so on...
}
}
// add the publication before the build even starts
// used ./gradlew mymodule:assemble --dry-run to find where to put it
afterEvaluate {
tasks.clean.dependsOn("publishToMavenLocal")
tasks.preBuild.dependsOn("publishToMavenLocal")
}
dependencies {
implementation "foo-aar-dependency:bar1:1.0"
implementation "foo-aar-dependency:bar2:1.0"
implementation "foo-aar-dependency:bar3:1.0"
// and so on
// also I had to make sure to add the aar's transitive dependencies as implementation below
}
Note: When I sync for the first time the dependencies are not found, but as soon as any clean/assemble is called the dependencies are published prior so it runs as it needs.
Note2: most of this can be moved into a separate file to not clutter your build.gradle
Note3: If you actually want to publish your module as a library this solution is not for you.
Note4: This also works on CI if you run clean then your next task.
For those who prefer to use as a regular dependency (or an item on your Gradle's version catalog):
Create a folder eg. spotifyAppRemote at the same level of app folder
Add the desired .aar file at the root of spotifyAppRemote folder
Create a settings.gradle.kts file at the root of spotifyAppRemote folder. This file will be empty, it just needs to be there for the composite builds. See: docs
Create a build.gradle.kts file at the root of spotifyAppRemote folder:
plugins {
base //allows IDE clean to trigger clean on this module too
}
configurations.maybeCreate("default")
artifacts.add("default", file("spotify-app-remote-release-0.7.2.aar"))
//Change group to whatever you want. Here I'm using the package from the aar that I'm importing from
group = "com.spotify.android"
version = "0.7.2"
Next add Gradle files to this folder to allow this module to build itself. You can do it manually or add the following snippet at the root of settings.gradle.kts (!! the project root, not the empty one created above)
/* Optional - automatically sync gradle files for included build */
rootDir.run {
listOf(
"gradle.properties",
"gradlew.bat",
"gradlew",
"gradle/wrapper/gradle-wrapper.jar",
"gradle/wrapper/gradle-wrapper.properties"
).map { path ->
resolve(path)
.copyTo(
target = rootDir.resolve("spotifyAppRemote").resolve(path),
overwrite = true
)
}
}
Now you can go ahead and add this folder as a module at the settings.gradle.kts on your project root. The same where may add the snippet above:
rootProject.name = "Your project name"
include(":app")
includeBuild("spotifyAppRemote")
Sync and build your project.
Now your included build will be available for your as a regular dependency with the defined group and version. To use this dependency:
dependencies {
// group:moduleName:version
implementation("com.spotify.android:spotifyAppRemote:0.7.2")
}
Thanks other members for the solution.
Source code on github: https://github.com/rsicarelli/SpotifySdkCompositeBuild
If you want to bundle a local .aar within your library and use that library in another project, you could take a look at "fat aars" https://github.com/kezong/fat-aar-android
EDIT : if the AAR does not contain android resources or native code, this could help you.
If you want this local resource directly linked to an "app" or "sdk" module
(no compileOnly)
=> Use a jar.
Rename the .aar to .zip
Extract it
Use the classes.jar inside
That's it.
Patch the problematic 3rd party dependency's build.gradle file. Under their dependencies { } section, they had a line like this:
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar']) //Load all aars and jars from libs folder
My patch changes that line to:
implementation(name: 'the-name-of-the-aar', ext: 'aar')
In my project's build.gradle, under allprojects { repositories { }, added:
flatDir { dirs "$rootDir/../node_modules/the-third-party-dependency/android/src/main/libs" }
Where the AAR file lives
It was tested with reactnative >= 0.69.x
I faced a similar problem:
Task: add .aar SDK inside another SDK
Solution:
We have to create new Android Library Module inside our library (right click on our library name -> module -> Android library )
Delete all files inside it
Insert our .arr inside this module
Create build.gradle file inside module and put there:
configurations.maybeCreate("default")
artifacts.add("default", file('your_arr_name.aar'))
Add to your library build.gradle inside dependencies block next:
implementation project(':your_library:your_arr_module')
Now rebuild project and everything should work fine
It is bug in Android Studio 4.0.+.However, there is a solution.
First, project/build.gradle:
allprojects {
repositories {
google()
jcenter()
mavenCentral()
flatDir {dirs "../MoudleA/aars,../MoudleB/aars,../MoudleC/libs".split(",")
}
}
}
Second, Moudle/build.gradle:
// MoudleA/build.gradle
repositories {
flatDir {
dirs 'aars'
}
}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
//api fileTree(dir: 'aars', include: ['*.aar'])
// aar
new File('MoudleA/aars').traverse(
nameFilter: ~/.*\.aar/
) { file ->
def name = file.getName().replace('.aar', '')
api(name: name, ext: 'aar')
}
}
// MoudleB/build.gradle
repositories {
flatDir {
dirs 'aars'
}
}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
//fullApi fileTree(dir: 'aars/full', include: ['*.aar'])
//liteApi fileTree(dir: 'aars/lite', include: ['*.aar'])
// aar
new File('MoudleB/aars/full').traverse(
nameFilter: ~/.*\.aar/
) { file ->
def name = file.getName().replace('.aar', '')
fullApi(name: 'full/' + name, ext: 'aar')
}
new File('MoudleB/aars/lite').traverse(
nameFilter: ~/.*\.aar/
) { file ->
def name = file.getName().replace('.aar', '')
liteApi(name: 'lite/' + name, ext: 'aar')
}
}
// MoudleC/build.gradle
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
//api fileTree(dir: 'libs', include: ['*.jar','*.aar'])
api fileTree(dir: 'libs', include: ['*.jar'])
// aar
new File('MoudleC/libs').traverse(
nameFilter: ~/.*\.aar/
) { file ->
def name = file.getName().replace('.aar', '')
api(name: name, ext: 'aar')
}
}
It works for me,You can also try.
You can upload the AARs to an Artifactory, and consume them.
In my case, I realised that I have created libs folder at wrong place then recreated folder in main folder and implementation fileTree(include: ['*.aar'], dir: 'libs') worked.
Adapt aar dependency to maven repo standards and depend on it.
Lets connect the dependency in build.gradle
repositories {
maven { url "$project.projectDir/libs" }
}
dependencies {
api "my-library-group:my-library-module:my-library-version"
}
Replace you libs/myLibrary.arr file with next files:
libs/my-library-group/my-library-module/my-library-version/my-library-module-my-library-version.aar
libs/my-library-group/my-library-module/my-library-version/my-library-module-my-library-version.pom
libs/my-library-group/my-library-module/maven-metadata-local.xml
Where my-library-module-my-library-version.aar is the original aar file
Content of my-library-module-my-library-version.pom
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>my-library-group</groupId>
<artifactId>my-library-module</artifactId>
<version>my-library-version</version>
<packaging>aar</packaging>
</project>
Content of maven-metadata-local.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>my-library-group</groupId>
<artifactId>my-library-module</artifactId>
<versioning>
<latest>my-library-version</latest>
<release>my-library-version</release>
<versions>
<version>my-library-version</version>
</versions>
<lastUpdated>20211130111015</lastUpdated>
</versioning>
</metadata>
Feel free to replace my-library-group, my-library-module, my-library-version with any value you like
Good news for everyone. It seems that we can finally include AARs without subprojects again. I was able to accomplish it using the implementation files directive as follows in the dependencies { } block:
implementation files('ssi.aar')
I also hit this issue when I increase my Android plugin version to 4.0.1, and it turns to error, tried some solutions but none of them are actually doable in our project.
Since we are using product flavours, and different flavours are using different local aar file, we simply can not just using api(name: "xxx", ext: 'aar') since those aar files are located in different flatDir.
For now I have to roll back to previous gradle plugin version.
will edit this answer if I figure something out
Much lazier way to do this in build.gradle.kts files is to use a fileTree combined with flatDir repository.
repositories {
flatDir {
dir("$rootDir/libraries")
}
}
dependencies {
fileTree("$rootDir/libraries").forEach { file ->
implementation(group = "", name = file.name.removeSuffix(".aar"), ext = "aar")
}
}
This way when you add or remove deps to the folder they are automatically configured
for me works this solution:
put into dependences in build.gradle:app file this string:
api fileTree(dir: 'libs', include: ['*.aar'])

Can android gradle resolve module libraries' dependencies automatically?

Setup
I have an android project setup in such a way that: Main depends on Module A and Module A depends on Module B.
Both A and B are compiled to aar files and uploaded to local maven repository. And in Main project, the importing of Module A is explicit.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile(group: 'com.test', name: 'ModuleA', version: '0.0.1', changing: true)
}
Error
When running the Main project, it failed with NoClassDefFoundError at places where Module A uses Module B.
This error is gone once I explicitly import Module B into Main project.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile(group: 'com.test', name: 'ModuleA', version: '0.0.1', changing: true)
compile(group: 'com.test', name: 'ModuleB', version: '0.0.1', changing: true)
}
Question
Can't gradle resolve the dependencies automatically? Or do I have to include all Module A's dependencies in the build.gradle of Main project?
I think it is related to the pom file generation, in pom file you can define dependency section. How do we let gradle know to include the dependencies in generating the pom file?
Edit #1
The build.gradle for ModuleA is like the following:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile(group: 'com.test', name: 'ModuleB', version:'0.0.1', ext: 'aar', changing: true)
}
publishing {
publications {
aar(MavenPublication) {
groupId packageId
version = versionId
artifactId libraryId
artifact("$buildDir/outputs/aar/${project.getName()}-debug.aar")
}
}
}
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = 'libs-release-local'
maven = true
username = "admin"
password = "password"
}
defaults {
publications('aar')
publishArtifacts = true
properties = ['qa.level': 'basic', 'dev.team': 'core']
publishPom = true
}
}
resolve {
repository {
repoKey = 'libs-release'
maven = true
}
}
}
What do you mean by "automatically"? If the dependency does not exist in a defined path with well-defined names in your gradle.build, it will not find it. What may be misleading is that references to libraries in repositories can include dependencies to other libraries. When gradle requests the library location, the server responds with a file that specifies the location and dependencies, if applicable.
An aar file does not include your gradle.build or another dependency file that gradle can use, so any dependencies defined in your Module A gradle.build are not available to your main gradle.build. So you can't expect gradle to go to the source location of your Module B because it isn't there.
I think libraries in repositories do not make this clear because if a library with dependencies is in a repo then those dependencies seem to "magically" be included when you do a build. This is because the library reference can include references to the other dependencies and gradle is given that information when it requests the library. The repo library entry/definition includes dependencies.
If this is the type of behavior you are looking for, you should put your aar in a repo (public or self-hosted) and then create an appropriate library definition in the repo (like a pom.xml file), specify the dependency and add the dependency library to the repo also.
EDIT:
Also gradle does not support parsing pom files natively. So you cannot directly reference a pom file to identify dependencies. However, it will work with repositories that identify dependencies (and those repositories can use pom files, but gradle does not parse them). See the docs here: https://docs.gradle.org/current/userguide/dependency_management.html
Also, see the related question about gradle's lack of support for parsing pom files: Reading info from existing pom.xml file using Gradle?
Finally find a solution for gradle to generate pom with dependencies, add the following to publishing task:
pom.withXml {
def dependencies = asNode().appendNode('dependencies')
configurations.getByName("_releaseCompile").getResolvedConfiguration().getFirstLevelModuleDependencies().each {
def dependency = dependencies.appendNode('dependency')
dependency.appendNode('groupId', it.moduleGroup)
dependency.appendNode('artifactId', it.moduleName)
dependency.appendNode('version', it.moduleVersion)
}
}

Cannot change dependencies of configuration (after enabling instant run)

I just enabled instant run in my android studio project. (Followed the instructions here)
My project contains git submodules and somehow these do not compile anymore.
This is the error i get:
Error:(8, 0) Cannot change dependencies of configuration
':libraries:my_library:classpath' after it has been resolved.
Any idea what could be wrong there ?
Top level build.gradle:
buildscript {
repositories {
mavenCentral()
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-alpha1'
classpath 'com.novoda:bintray-release:0.2.7'
classpath 'io.fabric.tools:gradle:1.+'
}}
Module build.gradle:
apply plugin: 'android'
apply plugin: 'io.fabric'
android {
defaultConfig {
versionCode 4850
versionName '4850'
compileSdkVersion 23
buildToolsVersion '23.0.1'
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/MANIFEST.MF'
exclude 'META-INF/NOTICE'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
useLibrary 'org.apache.http.legacy'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
[skip]
compile project(':libraries:my_library:sdk')
}
Library build.gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
}
lintOptions {
abortOnError false
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
compile 'com.android.support:support-v4:23.1.0'
compile 'com.android.support:appcompat-v7:23.1.0'
testCompile 'junit:junit:4.12'
}
gradle reads and executes all build.gradle files in all folders of the included modules. As the error shows, it also tries to execute the root build script of :libraries:my_library.
You have to change your settings.gradle and include the library project by setting its 'projectDir':
include ':app'
// Give your library project any module name, i.e. ':sdk'
include ':sdk'
// Then set the project path of the library module
project(':sdk').projectDir = new File('libraries/my_library/sdk')
With this settings.gradle you can reference the library project as gradle dependency with:
compile project(':sdk')
I had the same problem. I resolved it by removing the classpath in the submodule Top-level build.gradle file.
dependencies {
// classpath 'com.android.tools.build:gradle:1.0.0'
}
I'm not sure if it's the best thing to do, but it worked for me.
I had the same problem. I compared it to the (working) sample project by #RaGe and found the minor difference.
The sub project folder has to start with a Upper case letter.
Here is the change I did on #RaGes sample to break it and get it working again.
Broken structure:
android-multi-project-sample
+ .gralde
+ .idea
+ app
+ build
+ gradle
+ myApplication2
- .gitignore
- android-multi-project-sample.iml
- build.gradle
- gradle.properties
- gradlew
- gradlew.bat
- local.properties
- settings.gradle
results in the following error:
Error:(8, 0) Cannot change dependencies of configuration ':myApplication2:classpath' after it has been resolved.
Working structure (with upper case sub project)
android-multi-project-sample
+ .gralde
+ .idea
+ app
+ build
+ gradle
+ MyApplication2 // upper case!!!!!!
- .gitignore
- android-multi-project-sample.iml
- build.gradle
- gradle.properties
- gradlew
- gradlew.bat
- local.properties
- settings.gradle
also the top level settings.gradle has to be changed:
+ include ':app', ':MyApplication2:mylibrary'
- include ':app', ':myApplication2:mylibrary'
and app/build.gradle has to change this
+ compile project(':MyApplication2:mylibrary')
- compile project(':myApplication2:mylibrary')
Everything compiles
Be careful! Git is not case sensitive by default. Use
git mv -f myApplication2 temp
git mv -f temp MyApplication2
to rename the folder.
According to official documentation on instant run.
What happened behind the scenes is that we have updated your project’s build.Gradle file to use the latest version of the Android Gradle plug-in, which is required for Instant Run to work. We also update your Gradle wrapper version to 2.8, and attempt to update the build tools version in all your modules to the latest (23.0.2). This isn't required for Instant Run, but it will use a new faster version of dex, which helps both instant run and a full build be a bit faster.
A Snippet of Application\build.gradle is shown below:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-alpha1'
}
}
Known Issues Using Instant Run
Using Instant Run with Reflection
Reflection could show unexpected things, for example:
Classes are all made public
Many other things are also made public
Limitations with Performance Profiling
We suggest temporarily disabling Instant Run while profiling your debug application.
There is a very small performance impact when using Instant Run, and a slightly larger impact when methods are overridden.
Increases in App Methods
Instant Run adds some methods–140 plus three times the number of classes in your app and its local dependencies. If the app was previously just below the dex limit, enabling Instant Run may push your app over the dex limit. Learn how to fix this by Optimizing Multi dex Development Builds.
Other Known Issues
Intermittent issues may occur where the IDE loses connection with the app which will trigger a full rebuild.
Third party Gradle plugin compatibility has not yet been tested, especially those that have not been updated to use the new transforms API.
Data-binding is currently broken in this build (capability to be restored).
so if you are facing this issue then you can turn off you instant run
go to Settings → Build, Execution, Deployment → Instant Run and uncheck Enable Instant Run… .
Better understanding of instant run go here
Take your dependencies out of your top level build gradle. As it is you are creating a classpath with your top level gradle and then attempting to overwrite it with your other build.gradles
From:
buildscript {
repositories {
mavenCentral()
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-alpha6'
classpath 'com.novoda:bintray-release:0.2.7'
classpath 'io.fabric.tools:gradle:1.+'
}}
To: Note I did not add that commented line, Android-Studio does this automatically
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-alpha6'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
You should be able to add any needed Maven repositories into your separate app gradles, as they should be specific and the jcenter would cover many of these, as #AndroidMechanic, and #Hi I'm Frogatto have been trying to say in previous answers and comments.
Have a look at read here Bintray - JCenter
The other thing is, I do not understand why you are managing your libraries build gradle within your project as part of your project. You should be referencing your library from your project, with the app build.gradle. You are treating the library gradle as the app gradle.
dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
compile 'com.android.support:support-v4:23.1.0'
compile 'com.android.support:appcompat-v7:23.1.0'
testCompile 'junit:junit:4.12'
}
Make these changes, then see what duplicates and you can manage that from there.
Also, I recommend manually syncing project with gradle files when changes are made. I would not rely on instant anything, it's important to make changes step wise and take stock of what's occurring, particularly when it won't compile. That's my opinion only and one way to program in android.
If instant run creates havoc with a particular project, I would disable it for that project. It is enabled by default and I've had no issues with it. The build mess may be the result of unclear gradles in your project to begin with.
Also:
In gradle wrapper properties, grade 2.10 is required for classpath 'com.android.tools.build:gradle:2.0.0-alpha6':
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
See here for latest updates
Android Tools Project Site
Or you can install a previous version of Android Studio and use the previous working version of your project.
If you have multiple git files, I suggest you remove the redundant ones, keep only the ones you are using for version control.
classpath 'com.android.tools.build:gradle:2.0.0-alpha1'
try to change it to
classpath 'com.android.tools.build:gradle:2.0.0-alpha6'
alpha1 seems obsolete since today (?) and is not compiling any more.
Also you'll have to upgrade your gradle to latest 2.10 to work with alpha6
Two things you can try
Change your plugin for "android"
With the new gradle tools you need to specify the correct plugin for your module gradle file as well as your library gradle file. If you look closely, your library gradle file is correct:'
apply plugin: 'com.android.library'
Change your module gradle plugin:
apply plugin: "android" -> apply plugin: 'com.android.application'
org.apache classes are now depcrated
This could also be a possible reason as to why your application isn't compiling anymore. Remove this:
useLibrary 'org.apache.http.legacy'
See Deprecated List.
The library project's build.gradle seems to cause the configuration error (because of some obscure reason). For me it was enough to also add the library project (which is a git submodule) to settings.gradle instead of only adding the library's project module.
Instead of:
include ':libraries:my_library:sdk'
try including both the library subproject and the subproject's module:
include ':libraries:my_library'
include ':libraries:my_library:sdk'

Adding local .aar files to my gradle build

So I have created an Android library and successfully compiled it into a .aar file. I called this aar file: "projectx-sdk-1.0.0.aar". Now I want my new project to depend on this aar so what I have done is follow this post.
But the post confuses me since I do not get the desired result:
The package name of the aar is : com.projectx.photosdk and the module inside is called sdk
Here is my current project structure:
|-SuperAwesomeApp
|--.idea
|--gradle
|--App
|---aars
|----projectx-sdk-1.0.0.aar
|---build
|---jars
|---src
|---build.gradle
And here is my Gradle build file:
apply plugin: 'android'
buildscript {
repositories {
mavenCentral()
flatDir {
dirs 'aars'
}
}
}
android {
compileSdkVersion 19
buildToolsVersion "19.0.1"
defaultConfig {
minSdkVersion 11
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:gridlayout-v7:19.0.1'
compile 'com.android.support:support-v4:19.0.1'
compile 'com.android.support:appcompat-v7:19.0.1'
compile 'com.projectx.photosdk:sdk:1.0.0#aar'
// compile files( 'aars/sdk-1.0.0.aar' ) // Does not work either
}
EDIT
The errors I am getting:
Failed to refresh Gradle project 'SuperAwesomeApp'
Could not find com.projectx.photosdk:sdk:1.0.0.
Required by:
SuperAwesomeApp:App:unspecified
You put your flatDir block in the wrong repostories block. The repositories block inside buildscript tells Gradle where to find the Android-Gradle plugin, but not the rest of the dependencies. You need to have another top-level repositories block like this:
repositories {
mavenCentral()
flatDir {
dirs 'aars'
}
}
I tested this and it works okay on my setup.
With recent versions of Android Studio, tested with 1.3, to use local .AAR file and not one fetched from maven/jcenter repository, just go to File > New > New module and choose Import .JAR/.AAR Package.
What you will end up with is a new module in your project that contains very simple build.gradle file that looks more or less like this:
configurations.create("default")
artifacts.add("default", file('this-is-yours-package-in-aar-format.aar'))
Of course, other projects have to reference this new module with regular compile project directive. So in a project that uses this new module which is simple a local .aar file has this in it's build.gradle
[...]
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.1.0'
[...]
compile project(':name-of-module-created-via-new-module-option-described-above')
}
[...]
In Android Studio 3.1.3 with gradle 3.0.1.
Simply adding implementation fileTree(dir: 'libs', include: ['*.aar']) or implementation files('libs/app-release.aar') without any other flatdir works.
These days (over 1 year after this question) with Android Studio >1.0, local dependency does work properly:
The android sdk looks for dependencies in a default local repo of: $ANDROID_HOME/extras/android/m2repository/
In a local library project you can publish the aar to this directory. Here's a snippet that can be added to your module's build.gradle file (ex: sdk/build.gradle)
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost" + System.getenv("ANDROID_HOME")
+ "/extras/android/m2repository/")
pom.version = '1.0-SNAPSHOT'
pom.groupId = 'your.package'
pom.artifactId = 'sdk-name'
}
}
}
some reference gradle docs http://gradle.org/docs/current/userguide/artifact_management.html
In your library project, run ./gradlew uploadArchives to publish the aar to that directory
In the application project you want to use the library in, add the dependency to your project/app/build.gradle. compile 'your.package:sdk-name:1.0-SNAPSHOT'
For local dependency, the next gradle build should find the previously deployed archive and that's it!
In my case, I use the above for local dev, but also have a Bamboo continuous integration server for the Library that publishes each build to a shared Nexus artifact repository. The full library code to deploy the artifact then becomes:
uploadArchives {
repositories {
mavenDeployer {
if (System.getenv("BAMBOO_BUILDNUMBER") != null) {
// Deploy to shared repository
repository(url: "http://internal-nexus.url/path/") {
authentication(userName: "user", password: "****")
}
pom.version = System.getenv("BAMBOO_BUILDNUMBER")
} else {
// Deploy to local Android sdk m2repository
repository(url: "file://localhost" + System.getenv("ANDROID_HOME")
+ "/extras/android/m2repository/")
pom.version = '1.0-SNAPSHOT'
}
pom.groupId = 'your.package'
pom.artifactId = 'sdk-name'
}
}
}
In order to tell applications to download from my internal Nexus repository, I added the internal Nexus maven repository just above jcenter() in both "repositories" blocks in the project/build.gradle
repositories {
maven {
url "http://internal-nexus.url/path/"
}
jcenter()
}
And application dependency then looks like compile 'your.package:sdk-name:45' When I update the 45 version to 46 is when my project will grab the new artifact from the Nexus server.
With the newest Gradle version there is now a slightly updated way of doing what Stan suggested (see maving publishing)
apply plugin: 'maven-publish'
publishing {
publications {
aar(MavenPublication) {
groupId 'org.your-group-id'
artifactId 'your-artifact-id'
version 'x.x.x'
// Tell maven to prepare the generated "*.aar" file for publishing
artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
}
}
repositories {
maven {
url("file:" + System.getenv("HOME") + "/.m2/repository")
}
}
}
It seems adding .aar files as local dependency is not yet supported(Planned to be supported in 0.5.0 Beta)
https://code.google.com/p/android/issues/detail?id=55863
But the way you are using your library in dependency will only work if your library is on central maven repository or in the local maven repository.
Refer this for How to use local maven repository to use .aar in module dependencies.
http://www.flexlabs.org/2013/06/using-local-aar-android-library-packages-in-gradle-builds
This is for Kotlin DSL (build.gradle.kts) assuming you put the files in my-libs subdirectory relative to where the build file is located:
dependencies {
implementation(
fileTree("my-libs/") {
// You can add as many include or exclude calls as you want
include("my-first-library.aar")
include("another-library.aar")
// You can also include all files by using a pattern wildcard
include("*.jar")
exclude("the-bad-library.jar")
}
)
// Other dependencies...
}
For more ways to do this, see Gradle documentations and this post and this post.

Add Android Better Pickers as a gradle dependency

I first added the android support library and tested that I could use it. However when I add Android Better Pickers in this maven repository I get the following error:
Gradle 'bumble' project refresh failed: Could not find
com.google.android:support-v4:18. Required by: myapp:app:unspecified
com.doomonafireball.betterpickers:library:1.4.2
This is how I set up my dependencies in the build.gradle located in MyProject -> app.
dependencies {
compile 'com.android.support:support-v4:18.0.+'
compile 'com.doomonafireball.betterpickers:library:1.4.2'
}
Android Better Pickers has the following in it's build.gradle and is packaged as an aar.
dependencies {
compile 'com.android.support:support-v4:18.0.+'
compile 'com.nineoldandroids:library:2.4.0'
}
Anyone know of a solution?
EDIT
Android better pickers now has gradle support since v 1.5! Now it is really easy adding it as a library, just follow there guide and don't forget to do a clean AND gradle sync after you change your build.gradle. Parts of the answers to this question still applies for none gradle projects I however.
First Make sure your are pointing to right sdk in File >Project Structure >Android SDK
In order to use Support Jar you have to install Android Support Repository from SDK Manager. SDK manager icon is available in Android Studio tool bar.
Things you should know for knowledge :
1.There is no need to add any dependency in your main module, if that is already added in any one of your library module already. So remove support dependency from your main module.
Make it something like this :
dependencies {
compile 'com.doomonafireball.betterpickers:library:1.4.2'
}
2.There is some issue going on in dependency management in android studio (0.4.2) which is fixed for Android Studio (0.4.3) but till the release check this as well For any dependency related issues.
Import Google Play Services library in Android Studio
EDIT :
I have checked the github repository there is no gradle dependency for date picker.
So do the following
Download Repository from github
Copy the library directory inside root of your project or make a directory and keep all your libraries inside that.The below configuration is for direct in root and I have renamed "library "to datepickerlibrary
Modify the build.gradle comes with library
build.gradle inside data picker library module
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android-library'
android {
compileSdkVersion 17
buildToolsVersion '19.0.0'
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
}
}
}
apply plugin: 'maven'
apply plugin: 'signing'
version = "1.4.0"
isReleaseVersion = !version.endsWith("SNAPSHOT")
group = "com.doomonafireball.betterpickers"
repositories {
mavenCentral()
}
dependencies {
compile 'com.android.support:support-v4:18.0.+'
compile 'com.nineoldandroids:library:2.4.0'
}
Dependency in your main module's build.gradle should be like :
dependencies {
compile project(':datepickerlibrary') //if it is inside some sub directory you can give path like ':libraries:datepickerlibrary' depends on you
}
Add this line inside settings.gradle which is located in root of your Project directory:
include ':datepickerlibrary'
After these all checks, Do sync your project with gradle.
It worked for me, let me know if any issue comes.
ORIGINAL ASKER'S NOTES
I ended up doing something similar to the above and it worked great! What I did as a summary:
Downloaded and manually added the library as a dependency in Android Studio
Removed the following from the library's build.gradle (got a sonytype class not found exception or similar)
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: sonatypeRepo) {
authentication(userName: sonatypeUsername,
password: sonatypePassword)
}
Updated the library's SDK version to match the one I had installed.

Categories

Resources