Difference between three dependencies - android

in one example, I saw three dependencies block in build.gradle.
example:
root folder: build.gradle
1.
buildscript{
dependencies{
}
}
2.Under android block
android{
dependencies{
}
}
I see one more dependencies block on root folder
buildscript{
}
dependencies{
}
android{
}
First two are been explained in Android developer site.
1st: is applicable for complete project
2nd: per module.
I am not understanding what 3rd dependency block means.

It's a bit confusing because Android Studio by default shows both build.gradle files right next to each other (when using the Android view).
If you switch to the Project view you can see the actual structure and where the different build.gradle files are located.
The build.gradle (Project: MyApplication) file is in the root folder of the project and its configuration settings apply to every module in the project. A module is an isolated piece of the bigger project. In a multi-module project, these modules have their own jobs but work together to form the whole project. Most Android projects only have one module, the app module.
The build.gradle (Module: app) file here is in the app folder. Its build settings apply only to the app module. If there were another module, then the it would have its own build.gradle file, too. As an example, I made a library project with three modules: a library module, a demo app module, and another app module that I plan to use for testing. Each of them have their own build.gradle files that I can tweak.
In a basic project, almost everything you need to edit will be in the app module's build.gradle file. You can remember it like this:
You're making an app, so go to the build.gradle (Module: app) file.
Further reading
Configure Your Build (Android documentation--very readable and useful)
Introduction to multi-project builds (Gradle documentation)

First two are been explained in Android developer site. 1st: is applicable for complete project 2nd: per module.
It is not exact.
The buildscript block can be specified in the root level but also in the module build.gradle file.
These dependencies block only controls the dependencies for the buildscript process itself, not for the application code.
2.Under android block
android{
dependencies{
}
}
It is not correct.
The correct syntax is:
android {
...
}
...
dependencies {
...
}
Don't put these dependencies in the top-level file.

Related

How to add a class / an enum to settings gradle script on gradle 6.0+?

I want to add an enum called modules with the path of the sub module and some compilation types.
I used to have this in the buildSrc before gradle 6 and it was accessible in the settings.gradle
But from gradle 6.0, settings.gradle is compiled before buildSrc project. I have moved my enum to the settings.gradle, now it is not accessible to other project level gradle scripts.
The behaviour change is outlined in the below release notes.
https://docs.gradle.org/current/userguide/upgrading_version_5.html#changes_to_plugins_and_build_scripts
They suggest to add the enums / classes used in the settings.gradle to the build script closure, but I am not really sure how to do that.
https://docs.gradle.org/current/userguide/upgrading_version_5.html#plugins_and_classes_loaded_in_settings_scripts_are_visible_to_project_scripts_and_buildsrc
I've recently hit a similar issue, my company have custom code for authenticating with our Nexus which we were keeping in buildSrc. I can't turn this into a plugin since I'd need to store that in our Nexus and then would be in a catch-22 situation as I'd need to authenticate to get the authentication plugin!
I can see 2 potential workarounds for this:
Publicly published jar.
Build your custom classes as a separate jar, or a Gradle plugin if this fits the use case. Publish the jar to a maven repository that you can access from settings.gradle buildscript (for me this is difficult as it's sensitive company specific code).
This might look something like the following in your settings.gradle:
include "project-name"
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.companyname:gradle-utils:0.0.1'
}
}
Commit the binary
This isn't a desirable option but you can manage the source code for your custom buildSrc classes in another repository, then every time you make a change to them (hopefully infrequently) - you can build the new version and commit the built jar into the repositories that need to use it (perhaps under buildSrc). If your custom code has dependencies that aren't naturally on the classpath when gradle runs, you'd need to package these into the jar that you commit as well.
Your settings.gradle might then look like:
include "project-name"
buildscript {
dependencies {
classpath files("buildSrc/gradle-utils.jar")
}
}

Reusing the same code across multiple Android Studio projects

I have some code I'd like to use across multiple different projects. Let's say it's some e-commerce code that handles things like payments and shopping carts.
It seems inefficient and dangerous to copy-paste everything across different projects. And if I add one feature or fix one bug in the core e-commerce module, I'd like that change to be reflected in other projects using it too.
I would also like to re-use some of the Activities, Fragments, Adapters too.
What is a good approach to this?
When we have a library project that needs to be shared to every project on a local computer, we can make use of Maven.
A. Here the step in your library that we will you for the project:
Make a library project from Android Studio.
Add Gradle Android Maven plugin to root build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
}
}
Add apply plugin for step 1 in your library build.gradle. (NOT root build.gradle):
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
Add the following after the apply plugin, this line to determine your library when adding to project:
group = 'com.yourpackage.yourlibrary'
version = '1.0'
Add the following code in your settings.gradle:
rootProject.name = 'yourlibrary'
Then publish it to your local maven with:
./gradlew install
Or you can use gradle option in Android Studio.
Your library will be installed in $HOME/.m2/repository. Remember that to use the library you need to add like this:
Groupid:artifactid:versionid
Artifactid will be package name of your library.
B. Here the step in your Project which using the library:
Add the following code in your root build.gradle:
mavenLocal() // for local maven.
This for getting the local library maven that we have installed in step A
Then in your app project.gradle, add compile for the library:
compile 'com.yourpackage.yourlibrary:yourlibrary:1.0'
Read more:
Gradle: How to publish a Android library to local repository
https://github.com/dcendents/android-maven-gradle-plugin
https://inthecheesefactory.com/blog/how-to-upload-library-to-jcenter-maven-central-as-dependency/en
From my Knowledge 1. As others said try creating your own Module or Library and use it where ever you need 2.Use Version Control Tools Like Git(If your code changes it will be refleted in your git account)

What is the difference of two build.gradles in project root directory and in app folder?

I just noticed there are two build.gradle files in my project. Is it because I used gradle wrapper while importing the project?
In Android Studio what is the difference between build.gradle in project root directory and build.gradle in app folder?
The "app" folder is just one module. When writing more complex apps you may have multiple modules. The build.gradle at the module level relates only to that module whereas the build.gradle at the root relates to all modules in the project.
Example from project level build.gradle:
allprojects {
repositories {
jcenter()
}
}
This is saying all modules should use jcenter repository for resolving dependencies. Now a potentially confusing thing is a terminology clash between gradle and android studio. An android studio "module" is a gradle "project" hence "allprojects".

Android Studio - Build AAR to combine multiple modules/libraries [duplicate]

I am building android library project, which has a dependency on another internal library project.
I am wondering if there is a way to package a single AAR library, which already contains internal library inside it. I would like to share only 1 AAR library package to my application developers.
This is how my build.gradle files look currently, but currently they produce separate AAR files and both needs to be included in Application's build.gradle. As application is being built by another company, we need to share the final AAR file with them and not the complete library projects.
----- internalLib -------->>>>>>>>>>
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.+'
}
}
apply plugin: 'android-library'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion '18.1.1'
}
dependencies {
compile 'com.android.support:support-v4:18.0.0'
}
----- externalLib --------
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.+'
}
}
apply plugin: 'android-library'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion '18.1.1'
}
dependencies {
compile 'com.android.support:support-v4:18.0.0'
compile project(':internalLib')
}
There is no mechanism to combine library. It's a bit complicated as you probably want to control which dependencies get merged (for instance you probably don't want to include support-v4 in there). Also you'd need to merge the resources and Android manifest.
At this time there's no way to easily hack something, unless you are sure the resources have no conflicts between the two res folders (for instance you could have strings_a.xml in one lib and strings_b.xml in the other lib). This way you can just "merge" the two res folders by copying them both into the same location (as opposed to do a merge at the android res level).
For the Manifest it'd be more complicated, but doable with some custom code.
Providing a built-in mechanism for this is very low on our priority so don't expect it anytime soon.
For the sake you have to upload each library as separately on maven and use its implementation in parent library modules till the main library module. Only then when you publish your main library on maven will include your all child dependencies.
As far as we have only one option add aar as api dependency inside the module.
For that we have to generate aar file and publish it to Maven and make it accessible by another module and consume it in app.
https://developer.android.com/studio/projects/android-library
As mentioned above android developer document.
The library module with source code is copied to your project, so you can actually edit the library code. If you want to maintain a single version of the library code, then this is probably not what you want and you should instead add the compiled AAR file as described above.
If there anything else we can do, please let us know by jot down in the command section.
It is not supported
It is not recommended to include one library into another because it leads to a serious issues with managing versions and complexity of creating and supporting such solution.
You should stick to native approaches like dependency manager or rearchitect your codebase
[iOS Umbrella framework]

How to develop a library and an application side-by-side in Android Studio?

I'm currently developing both a library (with no activities) and an application that depends on the library. Currently, I have these as separate projects, and I can copy the generated .aar file from the library project into the application project's libs folder, and re-sync gradle. However, this is an inefficient process because I have to rebuild and manually re-copy the .aar file every time I make a change to the library project. My question is, how can I streamline this process so that my application automatically uses the library's most recently generated .aar file?
1) In your app's settings.gradle include your lib as a project:
include ':lib-project'
project(':lib-project').projectDir = new File('../path/to/lib/project/lib-project')
The path to your lib project is relative to the settings.gradle location on your filesystem
2) in your app's build.gradle add lib project as a dependency:
dependencies {
compile project(':lib-project')
...
}
how can I streamline this process so that my application automatically uses the library's most recently generated .aar file?
Option #1: Dedicated Library
Step #1: Put your app project and the library project as children of a common root directory for the overall project. For the purposes of this answer, I'll call these app/ and library/, respectively.
Step #2: In the top level (i.e., the common root directory), have a settings.gradle file that lists these modules:
include ':app', ':library'
Step #3: In the top level, have a build.gradle file that sets up the Gradle for Android plugin and any other common stuff of interest, such as:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
(note that the above file is what you get from a native Android Studio project, created by the IDE)
Step #3: In the library/ directory, have a build.gradle file that uses the com.android.library plugin
Step #4: In the app/ directory, have a build.gradle file that has compile project(':library') in its dependencies to pull in the library
It may be that your AAR is the deliverable, not the app (e.g., the library is an open source one for community use, and the app is a demo app). In that case, you might use debugCompile in app/ to pull in the local library project for debug builds, but have releaseCompile to pull in the AAR from a published source, to confirm that you can build from the same thing that users of the AAR use.
Most of my CWAC libraries are set up this way (e.g., cwac-richedit).
Option #2: Publish the AAR Locally
You can use the maven plugin and the uploadArchives task to upload to a local Maven-style repo:
apply plugin: 'maven'
uploadArchives {
repositories.mavenDeployer {
pom.groupId = PUBLISH_GROUP_ID
pom.artifactId = PUBLISH_ARTIFACT_ID
pom.version = PUBLISH_VERSION
repository(url: LOCAL_REPO)
}
}
Here, my constants are pulled in from a gradle.properties file, and LOCAL_REPO is a file:/// URL pointing to a local repo. You can then run gradle uploadArchives to generate the AAR and push it to the local repo.
Then, your app can have a maven { url LOCAL_REPO } closure in the repositories closure, and can pull in the AAR artifact from there as if it was coming from a public repo (e.g., Maven Central).
My CWAC libraries use the uploadArchives task, but only for publishing to my local mirror of my Amazon S3-hosted Maven repo.
This approach would be if you really wanted to work off of the AAR, but wanted to do so from multiple projects. Note that you can certainly publish this to some other sort of Maven repo (e.g., a Sonatype server) for enterprise use.
Option #3: Mod a Module to Point to the Library Elsewhere
This is Pavel Dudka's approach in his answer. I haven't tried this. Off the cuff, this would be a good approach if you want to depend upon the library from multiple apps, but you're not really concerned about having an actual AAR as a thing to distribute around.
And I'm sure there are other options than these three.

Categories

Resources