I've created an Android library project found here: https://github.com/dbotha/Android-Photo-Picker
The photo-picker library project itself has several dependencies of it's own:
// library build.gradle
dependencies {
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.squareup.picasso:picasso:2.5.2'
}
I've made this library project available on Maven Central so that it can be easily added to applications as a dependency:
// application build.gradle
dependencies {
compile 'ly.kite:photo-picker:1.1.2#aar'
}
The problem though is that when I come to add it as a dependency to a new Android application project it crashes because it can't find the Picasso dependency from the library project:
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.squareup.picasso.Picasso" on path
It's only when I explicitly add this dependency to the applications build.gradle do things work.
My libraries POM file dependencies looks correct: https://repo1.maven.org/maven2/ly/kite/photo-picker/1.1.2/photo-picker-1.1.2.pom
So I'm curious if applications that include my photo-picker library as a dependency always need to explicitly add all the photo-picker library dependencies too?
You are using the #aar notation.
It means that you want to download only the aar artifact, and no dependencies.
You can check this part of documentation:
Check the 1.4.1.2. Artifact only notation section:
An artifact only notation creates a module dependency which downloads only the artifact file with the specified extension. Existing module descriptors are ignored.
Using the #aar notation if you want to download the dependencies, you should add transitive=true.
I'd expect that omitting #aar it should work.
Related
Since version 3.0.0, the Android Plugin for Gradle allows you to export a module's dependencies to other modules.
As I understand it, this means that in my android library module I should be able to declare a dependency using api <dependency declaration> and access THAT dependency as an exported transitive dependency in my main app project, where I've declared my library module as a dependency.
I'm also using static file dependencies.
As an example:
I have a class NeededEverywhere, which is defined in its own gradle module everywhere-module. This module is in the same project as my library module.
//library module's build.gradle:
dependencies {
api project(':everywhere-module')
}
In my app's build.gradle (which is in a different Android Studio project), I declare my dependency on the library, but not the everywhere-module. This should mean that everywhere-module is an exported transitive dependency.
//app project's build.gradle
dependencies {
implementation files("path/to/my/library/file.aar")
}
However, I can't access the class NeededEverywhere in my app.
What am I doing wrong?
You are directly referencing an AAR.
Dependency information is not in an AAR, any more than dependency information is in a JAR. Dependency information is held in the metadata of an artifact repository, such as the POM file of a Maven-style repository.
So, the project with the library module needs to publish its AAR to an artifact repository. That could be one local to your machine (e.g., mavenLocal()). Then, projects that need to depend upon the library module do so from the repository, not via file(). Then, Gradle can get the transitive dependency information from the repository and make use of it.
I'm using Android Studio 3.0.1 and I'm trying to add an online dependency and while Gradle initially syncs without a problem it doesn't show my dependency in External Libraries and my code that references the dependency doesn't work.
Here's a snippet of what my build.gradle file looks like:
repositories {
mavenCentral()
maven { url 'https://oss.sonatype.org/content/groups/public/' }
}
dependencies {
compile group: 'com.fortysevendeg.android', name: 'swipelistview', version: '1.0-SNAPSHOT'
}
I'm pretty new to android development (took over an existing project from a dev who quit without leaving any documentation) so I'm not sure if this is a mistake with how to add a project dependency or if there is a problem with the dependency that I'm trying to add. Any help would be greatly appreciated!
I was able to get this to work by changing the dependency declaration to:
compile group: 'com.fortysevendeg.android', name: 'swipelistview', version: '1.0-SNAPSHOT', classifier: 'jar-with-dependencies'
The library artifacts up on the repository include an apklib and a JAR with a special classifier. The apklib format is not supported by Android Studio, and unfortunately the classifier on the JAR means that it's not accessible simply using the group-name-version format when declaring dependencies.
Your build.gradle file seems fine. If you want to keep the library specified as an external library, you can try and define the dependency using the alternative notation, replace:
compile group: 'com.fortysevendeg.android', name: 'swipelistview', version: '1.0-SNAPSHOT'
with:
compile 'com.fortysevendeg.android:swipelistview:1.0-SNAPSHOT'
The alternative approach is to download the jar file yourself and use it as a local dependency. If you navigate to the maven repository you can inspect the package which is included as a dependency and download the jar directly. Place the jar file in the libs folder of your project and add the following to your build.gradle file:
compile fileTree(dir: 'libs', include: ['*.jar'])
For further details on how to configure the dependencies of your gradle project, check out the Android Studio documentation here.
Based on the information you have provided, this should fix your issues. If this does not solve the error then there may be other issues with the project.
Your dependencies should not placed in the top-level build.gradle file where the repositories are defined. There is even a comment in that file that says so, by default.
You app dependencies should be the module's build.gradle along with the others like android-support
Additionally, that library is very old, and is a SNAPSHOT build, meaning it isn't meant to be generally used in a release environment. You should find an alternative... And there are plenty of other ListView swiping ones
I have created a android library and created aar file which has gradle dependencies of Glide library and when I use this aar as a library in my main project.But when i use the part of glide code in the library, it gives an error as no class found.When add the gradle dependency of glide library in the main project it works fine.Will this cause multidex issues?
The aar file doesn't contain the nested (or transitive) dependencies and doesn't have a pom file which describes the dependencies used by the library.
It means that, if you are importing a aar file using a flatDir repo you have to specify the dependencies also in your project.
You should use a maven repository (you have to publish the library in a private or public maven repo), you will not have the same issue.
In this case, gradle downloads the dependencies using the pom file which will contains the dependencies list.
Gradle dependencies difference between.
compile
apk project
compile project
provided project
implementation
My questions are
What's the difference between compile ,apk project, compile project,provided project here?
There's two separate things to discuss here: Dependency Configurations and Dependency Sources.
Dependency Configurations
Configurations help define the transitivity of a dependency, which in turn removes the pain of having to discover and specify the libraries your own project/library requires, including them automatically. This notion of configurations in gradle is very similar to that of Maven's scopes:
compile: Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects. A compile-time dependency is generally required at runtime.
apk: Defines a runtime dependency. A dependency with this scope will not be required at compile time, but it will be for execution. This means that you can save time while compiling and still have the dependency available when your project actually runs. This is a good example of when to use an apk dependency.
provided: It means that this dependency is available on the runtime environment. As a consequence, this scope is only available on the compilation and test classpath, and is not transitive. It is not supported on Android projects, though you can workaround it by defining your own configuration as discussed here.
There are more configurations that you can encounter on Android, such as testCompile, which allows you to specify a compile-time dependency that will only be used for testing, say you want to use junit in your tests, then you would do as follows:
testCompile 'junit:junit:4.12'
Dependency Source
Once you understand the configurations available for you, you need to specify an actual dependency. Dependencies might be internal or external, you may rely on another library you are working on, as well as on publicly available libraries. Here's where the project keyword comes in, allowing you to specify a dependency to an internal module or library. By defining a dependency as compile project, you are adding that module or library as a transitive dependency to your project.
Assume you have a project messages with three modules (producer, consumer and shared), the project structure would look as follows:
messages/
build.gradle
settings.gradle
consumer/
build.gradle
producer/
build.gradle
shared/
build.gradle
Now assume that both consumer and producer store messages in json format and that you want to use google-gson for that purpose. Assume that both projects have some common source code that they depend on, your shared module. consumer's build.gradle could then define the following dependencies:
dependencies {
// Internal dependency to project shared
compile project (':shared')
// External dependency to publicly available library,
// through public repositories such as jcenter() or mavencentral()
compile 'com.google.code.gson:gson:1.7.2'
}
To sum up, it is the combination of both configurations and sources that enables you to declare dependencies as compile, compile project, apk project and more!
My AAR includes a picasso library, but in my java code can't find picasso.
Here is my build.gradle:
and here is my multi-image-selector AAR gradle:
Why you not using only
compile 'com.squareup.picasso:picasso:2.5.2'
The aar file doesn't contain the nested dependencies and doesn't have a pom file which describes the dependencies used by the library.
It means that, if you are importing a aar file using a flatDir repo you have to specify the dependencies also in your project.
In your case you have to add in your app (not the library):
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.squareup.picasso:picasso:2.5.2'
If you use the gradle maven plugin to deploy the aar to a local repo, then you can get transitive dependencies to work. Here's how to do that:
How to use maven plugin to publish a library as an aar
How to enable transitive dependencies on the library dependency
Assume that you have one app and one library module. In your library module you use Picasso as dependency.
Let me explain step by step, with possible scenarios.
1- If you add your library module to your app module as the following :
implementation(project(":myLibrary"))
Your library works correctly.
2- If you add your library module to your app module as the following :
implementation files('../libs/mainLibrary-debug.aar')
You may get a crash if you don't put Picasso dependency to your app module. You have two options to get rid of this crash.
2.a.First option is to add Picasso library to your app module.
2.b.The second option is to compile you aar using any fat aar plugin. If you use a fat aar plugin, when you generate aar, it automatically downloads Picasso library and put it in aar. In this way, you don't need to add Picasso dependency into your app module. There are several fat aar plugins available, here is one of them : https://github.com/kezong/fat-aar-android