Migrating support to Android X: Are versions consistent across Modules? - android

I am migrating a big project to AndroidX.
On my former project, on the top build.gradle, I have defined a variable with the support library version so the 30+ child build.gradle's include the desired support version:
ext {
supportLibraryVersion = "28.0.0"
buildToolsVersion = "28.0.3"
googleServicesVersion = "15.0.0"
}
My question is, now that I have run the Android X refactoring, I see that dependencies have been converted to different packages under the Android X namespace and even out of it:
implementation "androidx.appcompat:appcompat:1.0.0'
implementation "androidx.percentlayout:percentlayout:1.0.0"
implementation 'androidx.palette:palette:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
My question is if now with Android X all module versions are synchronized so it makes sense doing in the top gradle:
ext {
androidXLibraryVersion = "x.x.x"
}
My guess is that modules outside the Android X namespace will have their own version schedule, but I am not even sure that the modules under AndroidX namespace will use common versions.
What do you think?

In the AndroidX world, every group (i.e., the part before the first : such as androidx.appcompat) can have a separate version as per the AndroidX Overview:
Unlike the Support Library, AndroidX packages are separately maintained and updated. The androidx packages use strict Semantic Versioning starting with version 1.0.0. You can update AndroidX libraries in your project independently.
As seen on the AndroidX releases page, they absolutely do upgrade at different rates, but the semantic versioning requirement ensures that stable versions of the libraries will continue to work together.

Related

Dependency 'androidx.appcompat:appcompat-resources:1.6.1'

Dependency 'androidx.appcompat:appcompat-resources:1.6.1' requires libraries and applications that
depend on it to compile against version 33 or later of the
Android APIs.
:app is currently compiled against android-32.
Also, the maximum recommended compile SDK version for Android Gradle
plugin 7.2.1 is 32.
Recommended action: Update this project's version of the Android Gradle
plugin to one that supports 33, then update this project to use
compileSdkVerion of at least 33.
Note that updating a library or application's compileSdkVersion (which
allows newer APIs to be used) can be done separately from updating
targetSdkVersion (which opts the app in to new runtime behavior) and
minSdkVersion (which determines which devices the app can be installed
on).
How do I fix this android studio roblem?
I clearly had no idea what should I do
This is a dependency version contrast issue just replace your appcompact and ktx with these
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'

How to limit max version of a transitive dependency

I have a problem about how to specify the max version for a transitive dependency. Let me explain this with an example:
My app uses the library library-foo, the problem is that library-foo version 3.0+ introduces breaking changes and my app is not ready yet. So I declare it in my dependencies:
implementation 'com.example:library-foo:(,3.0)'
My problem comes when I introduce a new dependency, lets say library-bar. That library introduces a transitive dependency on library-foo
library-bar 5.0 -depends on-> library-foo 2.2
library-bar 5.5 -depends on-> library-foo 3.1
So, after adding the new dependency:
implementation 'com.example:library-foo:(,3.0)'
implementation 'com.example:library-bar:5.+'
I was hopping the dependency resolution to be smart enough. Gradle included the 5.5 version, introducing the breaking changes in my project.
I know I could also limit the max version of library-bar but in projects with a lot of dependencies, it would be great to declare my max version of the troublesome library (foo in this case) forcing the rest of dependencies to be adapted to this.
Is it possible to do that?
You can use gradle's constraints:
implementation 'com.example:library-foo:3.0'
implementation 'com.example:library-bar:5.+'
constraints {
implementation('com.example:library-foo:3.0') {
because 'Versions greater than 3.0 introduce bugs'
}
}

Android: build.gradle error when adding firebase requirements

When I follow the firebase instructions and added:
classpath 'com.google.gms:google-services:4.2.0'
to the dependencies and:
implementation 'com.google.firebase:firebase-core:17.0.0'
to the dependencies as well, the all of a sudden I get an error on this line in the dependencies:
implementation 'com.android.support:appcompat-v7:27.1.1'
Here is the error message:
Dependencies using groupId com.android.support and androidx.* can not be combined but found IdeMavenCoordinates{myGroupId='com.android.support', myArtifactId='animated-vector-drawable', myVersion='27.1.1', myPacking='aar', myClassifier='null'} and IdeMavenCoordinates{myGroupId='androidx.lifecycle', myArtifactId='lifecycle-viewmodel', myVersion='2.0.0', myPacking='aar', myClassifier='null'} incompatible dependencies less... (⌘F1)
Inspection info:There are some combinations of libraries, or tools and libraries, that are incompatible, or can lead to bugs. One such incompatibility is compiling with a version of the Android support libraries that is not the latest version (or in particular, a version lower than your targetSdkVersion).
What shall I do? Why this happened after adding firebase?
(EDIT: THIS IS AN IMPROVED ANSWER OF THE ORIGINAL ANSWER WHICH IS GOT DELETED DUE TO CERTAIN ISSUES.)
Firebase migrated to AndroidX in the latest release. Which means that,
AndroidX maps the original support library API packages into the
androidx namespace. Only the package and Maven artifact names changed;
class, method, and field names did not change.
So latest firebase releases no longer supports for the old support libraries. You have to either downgrade firebase with,
implementation 'com.google.firebase:firebase-core:16.0.9'
or migrate your app to use AndroidX as mentioned below.(Anyway if your app depends on any com.google.android.gms or com.google.firebase libraries, you should prepare for this migration)
This release is a MAJOR version update and includes breaking changes.
With this release, libraries are migrated from the Android Support
Libraries to the Jetpack (AndroidX) Libraries. The updated libraries
will not work unless you make the following changes in your app:
Upgrade com.android.tools.build:gradle to v3.2.1 or later.
Upgrade compileSdkVersion to 28 or later.
Update your app to use Jetpack
(AndroidX); follow the instructions in Migrating to AndroidX.
With Android Studio 3.2 and higher, migration is lot easier. selecting Refactor > Migrate to AndroidX from the menu bar we can migrate to AndroidX.
And any maven dependencies can be handled as on below,
Maven dependencies that have not been migrated to the AndroidX
namespace, the Android Studio build system also migrates those
dependencies for you when you set the following two flags to true in
your gradle.properties file:
android.useAndroidX=true
android.enableJetifier=true
To migrate an existing project that does not use any third-party
libraries with dependencies that need converting, you can set the
android.useAndroidX flag to true and the android.enableJetifier flag
to false.

Why must $kotlin_version be explicitly specified in Android?

Supporting Kotlin in an Android studio project requires two dependencies: kotlin-gradle-plugin in Project/build.gradle and kotlin-stdlib-jdk7 in Project/app/build.gradle, and these two need to have the same version. The common method seems to be using a single kotlin_version variable which you then have to manually change when the IDE updates its Kotlin plugin — as of Android Studio 3.1.3, the IDE is still not able to automatically update the dependencies if you use a $variable as the version.
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
In non-Android Kotlin projects i.e. those using apply: 'kotlin' instead of apply plugin: 'kotlin-android', it is possible to simply omit the version from the kotlin-stdlib-jdk7 dependency, which will then be automatically resolved from the plugin.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
This even works on non-Android modules within Android projects. My question is, why is this not possible in Android modules? Why can't the $kotlin_version simply be omitted? If the feature has been present since Kotlin 1.1.2, why is it still causing compile errors on Android even on Kotlin 1.2.51? Or is it actually possible to do this, and if so, how can it be done?
In fact this is not Kotlin specific but has to do with how Gradle manages dependencies.
See https://docs.gradle.org/current/userguide/declaring_dependencies.html on how to specify the version of a dependency in Gradle.
In this case
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
is the standard way of setting the version. As the this version number is the same for several dependency it is declared in a variable in order to make it easy to change the version for all Kotlin libraries.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
Uses dependency constraints which are available since Gradle 4.6. It is used for the same purpose. One can set the version of a library in a central place and this way keep the version at a common value without having to go through all gradle.properties files of a larger project.

Android support library incompatiblity

I have a jcenter library ToggleButtons I develop that I import into my app. After switching to support 26.1.0 in my app, I receive this error:
All com.android.support libraries must use the exact same version
specification (mixing versions can lead to runtime crashes). Found
versions 26.1.0, 25.3.1
ToggleButtons:
com.android.support:cardview-v7:25.3.1
Main app:
com.android.support:design:26.1.0
I'm using other libraries such as Glide that reference even earlier versions of the support library (I haven't upgraded to 4 yet), but those don't have an issue. Have I designed the library improperly somehow?
This was always a recommendation, now they're making it generate errors.
You absolutely can't run an app with both versions, because that would cause duplicated classes errors. That means you must pick one of those manually now, while previously gradle would automatically choose one for you.
I'd suggest you use the higher number, since doing the opposite risks missing new features/assets that either library or app really depends on.
You can add this between your android and dependencies blocks in your application / library module's build.gradle for each conflict you must manually solve:
def supportLibraryVersion = '26.0.1'
configurations.all {
resolutionStrategy {
force "com.android.support:cardview-v7:$supportLibraryVersion"
}
}
I guess you get the idea of how it works.
Edit:
As noted by #eugen-pechanec the best practice is having all your support libraries with same version throughout all your projects modules. Also, it's best to use the same numbers on build tools (in module's build.gradle, inside android block).
Here's what your app depends on:
+ design:26.1.0
+ appcompat-v7:26.1.0
+ support-v4:26.1.0
+ recyclerview-v7:26.1.0
+ support-v4:26.1.0
Here's what the library depends on:
+ cardview-v7:25.3.1 (i.e. at least 25.3.1)
Here's what it means:
Card view library doesn't have any (runtime) dependency on other support libraries so technically in this case it's safe to use different versions. However this may change at any time.
More importantly your own code does not define cardview-v7 as a dependency so there's no way for gradle to know it should pull updated version as well.
The easiest fix then is just defining the dependency in your build.gradle:
def supportLibraryVersion = '26.0.1'
compile "com.android.support:cardview-v7:$supportLibraryVersion"
No force, nothing special. Upgrading a dependency is not a problem. Only downgrading is.
I still don't understand why Glide doesn't throw this error when they're using support 25.
As hinted above, Glide uses at least support-v4 25.x.x. And because a newer version of support-v4 is already requested by your own module, the dependency gets silently upgraded.

Categories

Resources