May 28, 2018 / Reading time: 6m
Getting that sweet com.androidx.* might not be as easy as one predicts.
You can skip to part 3. if you are aware of this year’s Android announcements.
This year’s Google I/O was quite surprising for me, I was really happy to know that the whole android team is working hard every year to make our lives as developers of the green robot easier every year.
Last year we got the first iteration of the Architecture Components, the first step into tackling some of the biggest issues we’ve had forever, lifecycle, configuration changes, persistence etc.
This year the team doubled down and formed the Android Jetpack.
Jetpack is a set of libraries, tools and architectural guidance to help make it quick and easy to build great Android apps. It provides common infrastructure code so you can focus on what makes your app unique.
Part of these changes was to unify the package structure of the android support libraries. If you’ve ever developed for android you are well aware of the whole mess that is the backwards-compatibility-libraries are: v4, v7, v13, v8, v?.
See for yourself: https://developer.android.com/topic/libraries/support-library/packages
We could already see some modularisation happening, the libraries were being broken into smaller pieces (com.android.support:cardview-v7, com.android.support:recyclerview-v7, (…)) making our projects more lightweight, but still not the perfect setup.
We’re not platform developers, so it makes sense to hide these small implementation details from the end-users, the developers, with the new package structure, we now clearer, unified, and explicit package naming:
"androidx.core:core-ktx:$versions.core_ktx" "androidx.fragment:fragment:$versions.fragment" "androidx.cardview:cardview:$versions.card_view" "androidx.appcompat:appcompat:$versions.appcompat"
No more support-library version included in the artifact.
android.* — bundled in the platformandroidx.* — extension library
Another very welcome change is the versioning system, each package has it own version, detached from the android API version, this way each extension library can be developed independently, I can imagine this helps the platform team to push more incremental updates, and more often.
Versioning changesThe new artefacts will follow Semantic Versioning, and will update independently, instead of all at once. Following this restructuring, it will be possible to update AndroidX libraries in your project independently. This avoids the problem of updating many Support Library modules in your project from e.g. 26.1.0 to 27.0.0 all at once.
First things first, there’s already an “official” guide for this migration, this article is just me documenting my experience.
Ok now Android Studio will scan your project and change the legacy imports to the new androidx.* structure.
This is when things start to get 🐟. I’ve read some people getting their projects completely broken, imports not mapping correctly, and if you are unlucky, you have a lot of manual work to do.
For this project most of the changes went well, I had the odd androidx.app.Fragment in the code with the old support.v4.Fragment as the class import type of “errors”, but for the most part, these weren’t too hard to find, ofc it helps the code base is fairly young, on the other hand. If this wasn’t your case, you can find the library mappings here, godspeed sir!
Next step, which I’m not sure if AS should automatically do, was to change/add dependencies on the module’s build.gradle, in my case, since this a multi-module-project I keep a separate versions.gradle file where I have all the dependencies and versions centralised, this way I ensure all my modules are including the same version (this prevents some odd errors) and makes maintenance easier. So I had to add all the new androidx.* packages as well the new versioning.
The versioning was where I spent most of my time, I had set the correct versions, or was I? While following the Add Architecture Components cheat sheet. I was setting the old version into the new androidx structure. Ok this took me 2 minutes to write and 3 hours to figure out, I even filed an issue on the best practices with Android Jetpack googlesample project, but finally called it a night, frustration tunnels your vision.
— I left the issue open since, to my knowledge, there isn’t an actual google-provided template for this (on a mature with some actual ui project).
But no, gradle was still complaining, not finding any of the new libraries, I deleted my .gradle folder, I restarted AS invalidated caches, and nothing, nothing was working.
The errors were very ambiguous too, the install task was failing, but no specifics were given, after a lot of trial and error I decided to comment out all androidx.* and old libraries from the build script, re-sync, clean and make the project, this was to force a cold-cache refresh. With no more gradle errors (didn’t even looked at the code), I re-added the androidx libraries and Architecture Components, pushed sync and behold! Gradle was finally downloading the libraries!
When I finally thought “this is it” it has to work now! Dagger2 started to break 😕, in the Android world, you never catch a break anyway. So I quickly went to the dagger2 repository and searched if any related issues had been opened.
And luckily someone else had done this, and the solution was simple add the jetifier, this is mentioned in the official guide and I had wrongly removed from the gradle.properties file.
(...) # Android X: https://developer.android.com/topic/libraries/support-library/androidx-rn android.enableJetifier=true android.useAndroidX=true
I kept a link to the Androidx refactor documentation for future reference, and to give more context to other developers.
Updated dagger to latest version and re-sync the project. Finally got what I wanted, DaggerAppComponent import available.
OSS tip: Be a good citizen and search, before opening duplicates :)
At this point I’m crossing my fingers 🤞… And it finally compiled! Yes! The app is running.
You just read the first article of a series where I’m going to document my experience trying out the new components.
P.S: On that commit the only changes done was really the package structure, although I’ve included a lot of the new libraries there is no implementation at all. Also there are some repeated libraries (support) in other modules.