Gradle 7, Are Android Build-Configuration documentations outdated? - android

Going through the documentation of Gradle's build configuration I can see several conflicts with my build on Android Studio 2020.3.1 using Gradle 7.0.3.
For example, in the documentation is says that allProjects block for repositories settings used by all modules should be added to the root build.gradle while in fact it only allows me to configure modules repositories in the settings.gradle under dependencyResolutionManagement block.
Another example is applying plugins to application modules, in documentations it says the first line should be:
apply plugin: 'com.android.application'
While the one used in my build is:
plugins {
id 'com.android.application'
}
What I also noticed is that also JitPack uses the same configurations suggested in that documentations page for using a JitPack published library in projects:
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.arcm111.ScaleNumberPicker:final:1.0.1'
}
So my question is, are these documentation pages outdated, is Gradle 7 not fully supported yet, or am I looking at the wrong documentation?

in the documentation is says that allProjects block for repositories settings used by all modules should be added to the root build.gradle while in fact it only allows me to configure modules repositories in the settings.gradle under dependencyResolutionManagement block.
You may wish to ask a separate Stack Overflow question with a minimum verifiable example and details of your errors. This GitLab repo, in tag v2.2 contains a multi-module Android Studio project using Gradle 7.0.2 that uses allProjects for configuring repositories.
Another example is applying plugins to application modules, in documentations it says the first line should be... While the one used in my build is
Either syntax works. The plugins approach has been available for a year or so in Android Studio projects. The project that I linked to above uses the older apply plugin syntax. This sample project, by contrast, uses plugins.
are these documentation pages outdated, is Gradle 7 not fully supported yet, or am I looking at the wrong documentation?
None of the above, AFAICT. allProjects and apply plugin still work, at least with Gradle 7.0.2.

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")
}
}

How to run "Watchface for wearos" codelab?

I am new to Android and WearOS and also to Gradle, and I just want to follow along this Codelab:
https://codelabs.developers.google.com/codelabs/watchface/index.html#0
So I downloaded Android Studio and imported the project
https://github.com/googlecodelabs/watchface
but when compiling I just get the error
Failed to resolve: com.google.android.support:wearable:2.0.0
I already tried to change SDK Versions and other things, but it didn't help.
I'm pretty sure it's just a few version settings, but I have no idea where to look.
Did anyone maybe complete this codelab and made it run with the "actual" version of AndroidStudio?
thanks,
Thorsten
The code on github was last updated in May 2017, which is a shame, as it is a useful introduction to watchfaces. A number of things have changed since then. There is even a pull request on github with gradle updates from Nov 2018, but it hasn't been merged.
Your 'Failed to resolve' error is likely related to Google now providing some packages in their own Maven repository, in addition to jcenter.
This can be fixed by adding google() to the repositories closures in the Package build.gradle file:
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
}
}
allprojects {
repositories {
jcenter()
google()
}
}
The version of the gradle plugin has been changed to 4.0.2 above too, so also update the file gradle-wrapper.properties with:
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
Gradle should now build, but it may still log some warnings or errors in the Build window which you can open at the bottom of Android Studio.
The gradle dependency keyword 'provided' has been replaced with 'compileOnly' and 'compile' with 'implementation'. Shift+Ctrl+R in Android Studio will enable you to easily do the replacement project-wide.
It should also be useful for updating compileSdkVersion and targetSdkVersion (to 30) and buildToolsVersion (to 30.0.2) in all the module build.gradle files.
The package versions are out of date, with the wearable ones currently at 2.8.1 and play-services-wearable at 17.0.0. Ctrl+Alt+Shift+S takes you to 'Suggestions' in 'Project Structure', which can help you in future to stay current.
The last problem is that the Android Support Library has been obsoleted in favor of jetpack/androidx. See the old reference.
In this project, it is only a problem in the build.gradle of module 5-palette. You may replace 'com.android.support:palette-v7:23.3.0' with 'androidx.palette:palette:1.0.0'. See Jetpack Artifact Mappings. You then need to change the import statement in MyWatchFaceService.java.
Finally add the following line to gradle.properties:
android.useAndroidX=true

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)

Best practice for buildscript tag in build.gradle of library projects

I'm wondering what is the best / intended way of defining build script repositories and dependencies for Android library projects.
Out in the wild (like Github) most of the repos define the following in there build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
} }
But if I create a library project in Android Studio this buildscript block does not get created, as it is already in the root build.gradle file, and therefore not necessary (I assume).
So what is the proper way, only defining it once in the root build.gradle or for each library project (which also means updating the version number for each library in case of new plugin versions). Or does it depend whether I want to release the library independently from my main application?
If you're developing a library, there isn't really a top-level build.gradle: that top level applies to all modules in a multimodule project, but a library is best implemented as a standalone single module.
Probably the best practice would be to have a single build.gradle file for your library module, and include a buildscript block in it with the repository and Android plugin Gradle version. That way it stands alone better, and it's not implicitly dependent on being in a project that has a top-level build.gradle file.
There's a huge caveat which kind of renders a lot of this moot, however -- if you include this module, with its own buildscript block, in a project that has a top-level build.gradle with a competing buildscript block, the top-level build file will win and it will ignore the block in your module.
This probably isn't much of a problem, but if your module relied on a specific version of the Android Gradle plugin, for example, and it was in a project that used a different version of the plugin, then your module would lose and it could run into problems. Another way of saying it is that it can only use one version of a plugin for all of the modules in a single build, and I believe the first one to specify it sets it for everyone.
In practice, this is only likely to be an issue if you rely on some feature specific to a later-than-1.0 version of the Android Gradle plugin, and it's included in a project that uses 1.0.
There are some subtleties here that I'll mention but won't answer (and I apologize for answering your question with more questions) -- if anyone else knows for sure, please answer yourself, or edit my answer, or mention it in the comments:
What if your buildscript block adds new plugins to the classpath? Do they get added or are they ignored?
What if your buildscript block adds new repositories to the search path? Will they get picked up?

Studio failed to download library from gradle repository

I already saw this question, but it is not helping me. First of all, I tried to add google play services in my project using:
dependencies{
compile 'com.google.android.gms:play-services:6.5.87'
}
It was showing me error:
Then I updated my studio to 1.0.1 and gradle to 1.0.0. And then I again synced the project with gradle. And it worked! It showed me another option despite of two options shown in above screenshot. It was "Install the library"(something like that). I clicked it and it popped up a dialog, and I installed the library(it was like downloadind using SDK manager and not like gradle downloads).
Now, I tried to download this library using:
compile('com.fortysevendeg.swipelistview:swipelistview:1.0-SNAPSHOT#aar') {
transitive = true
}
And it gives me error:
My android repository is updated:
Also, my internet connection is working fine. I tried to sync project many times, but same error all the time. I am not running gradle in offline mode:
How to fix this? And what is the permanent solution? And why is all this happening?
I found this question: Studio failed to download library from gradle repository which describes the exact same error, and that question had this bit of build script that you need to add to the build file that has the dependency statement in question:
repositories {
maven { url 'http://clinker.47deg.com/nexus/content/groups/public' }
}
When I do this, it works for me.
As to the general question of why this happens (and the better question of why the solution is different for different libraries):
Gradle, the build system that Android Studio uses, has the ability to automatically download library dependencies from the Internet. By and large this is a big boon for developers, because instead of having to manually download archive files, put them in the right place in your project, check them into source control, and repeat the process for new versions, now you just have to add a line of build script and the build system takes care of the housekeeping for you. The major downsides are Internet connectivity woes, which affect different developers to different degrees, and some added confusion about what it means when you get an error.
How does Gradle know where to download dependencies? Most Gradle build scripts contain a block that looks like this:
repositories {
jcenter()
}
or it may be mavenCentral() instead of jcenter(). This tells the build system to look in the JCenter or Maven Central global repositories (and JCenter is in a simplistic way of thinking about it a value-added mirror of MavenCentral); these contain archives of many versions of many, many, many libraries and are very convenient to use.
You can specify other repositories as well. This swipelistview library hasn't been uploaded to Maven Central, so the developer has made a repository for it available via a URL: if you add that URL to your repositories block, it will look for it there.
I was worried about the fact that you're accessing a SNAPSHOT version of the library -- these are supposed to be unpublished by definition. But adding a dependency on the snapshot version of the library in my test project worked for me, and looking around that URL in a web browser reveals that there's only a "1.0-" (trailing dash included) version of the library, so there's some subtletly there I'm missing; if you know more, please edit my answer or comment.
In any event, there are a couple caveats to this explanation. Some libraries aren't on Maven Central or on any Internet-accessible archive (at least they're not officially published by Android), but are instead published as part of the Android SDK download and maintained via the SDK manager. The Android support libraries and Google libraries fall under this category. If you get errors about those not being found, you have to fix it via the SDK manager.
How does the build system know to look in the SDK for those, since you didn't tell it via the repositories block? This behavior is hardcoded into the Android Gradle plugin.
The other caveat is that there's a detail that trips up a lot of people, which is that you actually have two repositories blocks, though with the usual Android Studio setup they're often in different files. One is in a buildscript block, which usually lives in the top-level build.gradle file and looks like this:
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
}
}
The other often also lives in the top-level build.gradle, but you can augment it with another block in your module's build.gradle file. The top-level one looks like this:
allprojects {
repositories {
jcenter()
}
}
and a module-level one would look like one of the previous examples in this answer. What do all of these mean?
The buildscript block tells Gradle where to find build system plugins. These are plugins that enhance the functionality of the build system itself but don't say anything about your actual project. In Android projects, the Android Gradle plugin is in this category, and unlike the Android/Google libraries, this one does live on Maven Central. The repositories block (in coordination with the dependencies block, which is not the same as the dependencies block for your project, keep reading) in buildscript tells the build system where to go look for these plugins.
The allprojects block in the top-level build file tells the build system to apply the bit of contained script to all build files in the project. In this example, it's telling it to add a repositories block pointing to JCenter to all subprojects. This is a convenience so you don't have to copy/paste it into multiple build files in your modules.
In your modules, you also have a repositories block, which in conjunction with the allprojects thingy, tells the build system where to go to get library dependencies for your project, as was previously discussed.

Categories

Resources