Converting your Android App to Jetpack
Google has rebranded their support libraries to be named Jetpack (aka AndroidX). Developers will need to make changes to account for this.
This article will explain what this means, and how to get started converting your project to use the new components.
What is Jetpack?
Android Jetpack is a set of libraries, tools and architectural guidance that is designed to make it easy to build Android apps. It is intended to provide common infrastructure code so the developer can focus on writing things that make an app unique.
It is a large scope effort to improve developer experience and collect useful tools and frameworks into a cohesive unit.
This quote from Alan Viverette (Android Framework team) is a good summary:
“Jetpack is a larger-scoped effort to improve developer experience, but AndroidX forms the technical foundation. From a technical perspective, it’s still the same libraries you’d have seen under Support Library and Architecture Components.”
Why is Google going through all this trouble (and creating all this trouble for developers)?
- Create a consistent namespace (androidx.*) for the support libraries
- Support better semantic versioning for the artifacts (starting with 1.0.0). This enables them to be updated independently.
- Create a common umbrella to develop all support components under.
It is important to mention — this current version of AppCompat(v28.x) is the final release. The next versions of this code will use Jetpack exclusively. It is imperative that developers are aware, and make the switch early.
This quote from Alan Viverette sums this up nicely:
There won’t be a 29.0.0, so Android Q APIs will only be in AndroidX
What is in Jetpack?
The answer: everything.
Jetpack is a collection of many of the existing libraries we have been using forever (like AppCompat, Permissions, Notifications or Transitions) and the newer Architecture Components that were introduced in recent years (like LiveData, Room, WorkManager or ViewModel).
Developers can expect the same benefits they got from AppCompat, including backward compatibility and release cycles that aren’t dependent on manufacturer OS updates.
Do you have to upgrade now? Can you update only parts of your code?
You don’t have to update today, but you will have to update sometime in the near future.
The current version of AppCompat (v28.x) is exactly the same as AndroidX (v1.x). In fact, the AppCompat libraries are machine generated by changing maven coordinates and package names of the AndroidX codebase.
For example, the old coordinate and packages were:
and are now:
It is important to note, you cannot mix AppCompat and Jetpack in the same project. You must convert everything to use Jetpack if you want to upgrade.
First Step — Upgrade your app to latest Support libs
When you are ready to update to Jetpack, make sure your app is upgraded to the latest versions of Gradle and AppCompat. This will ensure the refactor is only changing package names, and are not bigger issues related to library updates.
Updating your project is super important, and will expose any issues you will have with moving forward, such as a lingering dependency on an older version of a library. If you aren’t able to update to the latest versions, you will need to fix those issues before proceeding.
Don’t forget to check: https://maven.google.com for the latest Gradle dependency info.
Use the Refactor tool to update your Project
Once you have upgraded your project, you will use an Android Studio (AS) utility to do the refactor.
Run it from the menu: Refactor\Refactor to AndroidX:
This tool will scan your app, and show you a preview of the changes necessary:
If you are happy with the changes, select the “Do Refactor” button, and the conversion tool will do the following 3 things:
- Update your imports to reflect the new package names:
- Update the Gradle coordinates of your dependencies
- Add 2 flags to your gradle.properties file. The first flag tells the Android Plugin to use AndroidX packages instead of AppCompat, and the second flag will enable the Jetifier, which is a tool to help with using external libraries (see next section for details):
In general, the changes should be isolated to just these 3 areas, but in my experience, I have seen the refactor tool also make other changes. In my case, the tool added code to account for Kotlin Nullability (it added a few !! in my source code), but there likely will be other changes. It is a really good idea to closely monitor all the changes the tool makes, and ensure you are comfortable with them.
The AS refactor tool only makes changes to the source code in your project. It doesn’t make any changes to libraries or external dependencies.
For this, Google has created a tool named Jetifier that is designed to automatically convert transitive dependencies to use AndroidX libraries at build time. If we didn’t have this tool, we would need to wait for every 3rd party lib to update, before we could use it (and delay our update until this was ready).
Other than enabling this tool using the gradle flag, there isn’t much to know about using it, since this is an automated process, and no configuration is required.
Google recently announced a stand-alone option for running Jetifier. You can even run a “reverse mode” which will “de-jetify” code (which will be very useful for debugging).
Problems you may encounter
You may discover a 3rd party library that needs to be updated. For example, someone discovered the current version of SqlDelight required an old version of the Room persistence library. They requested an update, and Square has already provided the updated version of the lib. If you discover an issue, the sooner you can request an update from the developer the better. The newest version of Room (v2.1) already requires AndroidX, which likely will cause many folks to upgrade. As of this writing, the Facebook SDK is not updated, and this likely will be a blocker for many people.
Updating your project to the latest versions of AppCompat may not be trivial. You may have workarounds in your code for previous bugs or encounter upgrades that require significant re-work. Plan ahead to account for this work.
Source files are not modified by Jetifier, so this may be confusing when using documentation.
You can’t Jetify by Module, so this is an “all or nothing” operation on your codebase. This may require blocking ongoing development until this is resolved — otherwise you probably will encounter huge merge nightmares.
The mapping tool may insert alpha dependencies into your code (for example ConstraintLayout alpha is added).
Android Studio may not know about the Jetifier and display errors (red squigglies). Doing an Invalidate Cache and Restart should fix this.
Jetifier doesn’t modify generated code, which may require additional rework.
Some of the replacement names are not correctly mapped (these seem to be primarily from the design lib). The refactor tool won’t work for these cases, and your code won’t compile. To resolve these, you will need to manually resolve the imports. Hopefully, these issues will be minimized over time, as the tools mature and the bugs in the refactor tool are fixed.
The standard naming convention for Jetpack is to duplicate the package name into Maven coordinates. In Jetpack, the package will always match the groupid.
For example, if you know the package name was `androidx.webkit` then the dependency will map to: `androidx.webkit:webkit:VERSION`.
Plan ahead for the changes required by the migration to Jetpack, which will be required moving forward. The hardest part of the upgrade will likely be updating your project to the latest dependencies.
There are likely 3rd party libraries that haven’t been updated yet. It is important to identify these early and ask the developer to update them.
Full mapping of the old class names to the new ones, which can be useful if you have issues with the automated refactoring, or need to figure out a specific change.
Great article from Dan Lew, highlighting his experiences (and issues encountered) refactoring his project.
Introduction to Jetpack Blog Post from Android Developers.
Thanks to Elliot Mitchell for the proof-read, and inspiration!