Implementation vs API using maven dependency - android

I have a utility library that I have pushed to a JFrog artifactory.
Now I am able to include that library in another project through gradle implementation (Not including it as a submodule, but getting it from local maven repo).
My question is the utility library uses some other libraries which my main project also requires.
Now, in my understanding using "api" with internal dependencies of my utility library, should have allowed those dependencies to be available to my main project, but it's not happening.
I wanted some clarification on this as to how I can allow my library internal dependencies to be available to my main project. Because, otherwise I will just be importing them again in my main project, which I do not want to do.

Related

Achieve modularization in android, I want SDK to work with optional dependencies. Whether dependency is provided or not code should compile in both

I am creating SDK and want to modularize it.
And prevent internal APIs from being exposed on your public interface.
Want optional dependency based on features required. If features is not required we can remove dependency and code and imports should not work.
Tried Ways
Submodule dependencies
Fat AAR
Submodule dependencies
when a library module gets built, the .aar artifact will only include code and resources that are in the library module itself. It won’t include:
any code or resources from database and ui-components
links to its transitive dependencies (these go into the build.gradle)
So when the app module directly includes the library as a gradle dependency, it would crash due to missing classes from database and ui-components on its classpath.
Fat AAR
In the fat .aar solution, code and resources of the submodules are bundled into the main SDK module, hence creating a fat .aar
the fat .aar plugin breaks on almost every minor Android Gradle plugin update! This is because it hooks itself into particular tasks of the Android Gradle plugin and these very often get renamed/moved. However, the project maintainer need to do job at fixing those within a few weeks after the breaking change.
Also, because of the way fat .aar references dependencies from submodules, it can significantly increase the binary size of your SDK.
Is there any other possible solution?

Understanding "repositories" tags

I am confused why same repositories tags are required in multiple places in an Android project. Why don't we have all repositories under one tag, and the compiler searches everything from there.
My particular case is:
I created a library module and added it in a project. In my library gradle file, I have:
implementation 'com.github.jkwiecien:EasyImage:1.3.1'
for which I added maven { url "https://jitpack.io" } in repositories tag in the library's gradle file. I want EasyImage in the library only, not in the project. But it wont compile until I added this same jetpack.io in Project's app/build.gradle file. Why do we need to do this?
I want to distrubute my library and I don't want the users to add things that are already added in my library and are not required by their project.
Edit:
If you put jitpack repository url in your Project level build.gradle instead of app level build.gradle it will work for both. When you upload your library to JitPack, it automatically 'builds' your library for you but in your case your library is being built locally so it needs the repository url in each build file to build them separately. However you should keep the repository url in your library because eventually you will be distributing it and JitPack won't be able to build your library module if you have the url in your project build.gradle file instead of repository.
Previous Answer:
From what I understand:
You are using EasyImage in your library, and when you add the ibrary to your project, you want to use the same EasyImage library that you loaded in your library instead of adding it to your project.
if you load your library using 'implementation' like this:
implementation 'com.github.you:yourlibrary'
you will not be able to access dependencies that 'yourlibrary' uses. But if you load it using 'api'
api 'com.github.you:yourlibrary'
Now you can access EasyImage from this library instead of adding it again.
This was added in Gradle 3.0 and it works the same way as 'compile' keyword used to work(which is deprecated now). You should checkout this article for detailed explanation.
Why this behavior?:
By using imepentation,
if any implementation in EasyImage is changed, Gradle just needs to recompile EasyImage and Your library as any other class which does not import your library directly cannot use any implementation of it.
But if you use api to load library, If any change is implemented inside EasyImage, gradle needs to recompile EasyImage, Your library and all other modules which import your library as any other module might use implementation of EasyImage (like your app).

How to use a Gradle dependency with local modifications?

I have an Android application using an Android library. The library is a pretty big open-source project on GitHub, and its authors publish the artifacts to Bintray. I can specify the dependency with the usual syntax dependencies { implementation 'group:artifact:version' } in the app's build.gradle.
Now I want to change some code in the library. I git clone it on my machine, I make my changes, then I build the library. But how can I tell my app to use the library I built locally, instead of the one in Bintray?
I don't want to follow the approach in Gradle Local Project Dependency, because that means that the library code is now part of the application project, but I really want to keep things separated.
I think the solution involves publishing to a local Maven repository. I followed the guide at https://proandroiddev.com/tip-work-with-third-party-projects-locally-with-gradle-961d6c9efb02 but the app's Gradle is still picking the original library from Bintray.
Bintray-based projects have the install task. That's the one to be used instead of publishToMavenLocal.
When using install, the artifact version is automatically set to X.X.X before publishing to the local repository. Therefore, in order for the app to pick up the local library, you have to edit the implementation row to group:artifact:X.X.X.
As the guide https://proandroiddev.com/tip-work-with-third-party-projects-locally-with-gradle-961d6c9efb02 suggests, you also need to add mavenLocal() as the first entry in the repositories section in the top-level build.gradle of the application.

Auto import dependecies from my library

I created an android library that acts as a wrapper. I use some dependencies in the library notably Volley and Google Play Services. When I try to paste the .aar file in the project and compile it these libraries are not being imported and they throw an error. When I manually add these dependencies in the build.gradle of the new project then they work fine.
Is there way so that whenever my library is added it will auto import all the required dependencies?
just a friendly warning: including dependencies is considered a very bad practice at SHOULD BE AVOIDED.
However, if you do still want to do that, I suggest using the "download library from Maven" feature in Android Studio as described here.
This will make sure the library and all of its dependencies are downloaded.

Create a library with dependencies in android

I created a library 'LibA' which has dependencies on many 3rd party libraries like RecyclerView, EventBus etc. When i tried to include it in another project as an aar, Library was included successfully but dependencies did not came in aar.
Q1 How can I include dependencies in LibA, so that when some other project includes this library, it should not worry about internal dependencies of my library.
Q2 How does gradle manages dependencies of libraries, does it downloads all depenedencies at once, or first checks which are already available in the main project?
Q3 When someone includes a library from jcenter, does that brings all the dependencies with it?
Any help will very much appreciated. :)
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.
Q1 How can I include dependencies in LibA, so that when some other project includes this library, it should not worry about internal dependencies of my library.
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.
Q2 How does gradle manages dependencies of libraries, does it downloads all depenedencies at once, or first checks which are already available in the main project?
Gradle handles the dependencies for you. It doesn't add the same dependency twice or more.
Q3 When someone includes a library from jcenter, does that brings all the dependencies with it?
As said before, in this case the dependency has a pom file which describes all the nested dependencies. Gradle downloads it automatically.
Q1 How can I include dependencies in LibA, so that when some other project includes this library, it should not worry about internal dependencies of my library.
You should use some Dependency manager. For example Maven Central which has .pom file which defines all additional dependencies which should be used
Q2 How does gradle manages dependencies of libraries, does it downloads all depenedencies at once, or first checks which are already available in the main project?
gradle downloads all necessary dependencies. It creates a graph for dependencies, try to solve conflicts and download them
Q3 When someone includes a library from jcenter, does that brings all the dependencies with it?
If additional dependencies were not defined in pom file they will not be downloaded, only library

Categories

Resources