Migrating to AndroidX

AndroidX was announced in May of this year and has had regular releases and updates since then. We're starting to see libraries migrate to AndroidX which means we'd also need to migrate to keep using the latest versions of those. As a result, we decided it was time to test out the waters.

With AndroidX's Jetifier, we also keep compatibility with any libraries that haven't made the switch. This writeup is a breakdown of how it worked out for one project.

First, using Android Studio's "Refactor > Migrate to AndroidX" menu option was quick. It handled updating gradle support library dependencies and references to those dependencies throughout the app.

Then came the first hangup. There were many places where instead of just changing the import statement for a class (Fragment, for example), it changed the import and also directly referenced the class as well. Our fragments ended up looking like this:

import androidx.fragment.app.Fragment

class MyFragment : androidx.fragment.app.Fragment() {
    // our fragment

While it was simple enough to replace this throughout the app, it wasn't the only class that it happened to. An even easier way to clean this up would be to check out the differences in git and only include the import changes.

The affected classes included:

  1. Fragment
  2. RecyclerView
  3. ViewPager
  4. Snackbar
  5. CoordinatorLayout
  6. DialogFragment
  7. SwipeRefreshLayout

Additionally, classes related to these were also directly referenced. This included classes like FragmentManager and FragmentTransaction for Fragment, Adapter and ViewHolder for RecyclerView, and OnPageChangeListener for ViewPager, etc. Not the end of the world, but something to be aware of before checking in the changes.

I was unable to determine why that happened, and it might've been corner case for us. Or someone else could run into the same issue with more or other classes. The solution took just a little bit of cleanup, and it wasn't too troublesome.

We were using Koin in this app, so it needed to be updated to AndroidX-compatible versions. Again, that was a quick change. We were able to take advantage of the libraries mentioned in the first paragraph that had new AndroidX versions as well.

The final change to ensure our tests still worked was adding a reference to androidx.test:rules:1.1.0. Our ActivityTestRule using android.support.test.rule.ActivityTestRule worked before and was updated to androidx.test.rule.ActivityTestRule in the import statement. However, it wasn't included in the migration of the libraries.

The final issue didn't take long to find and fix, but someone else might run into it later.

Overall, the experience wasn't as painful as someone might expect. Major overhauls like this with interdependencies can be scary, but the reality wasn't in this case. We're going to do a full round of testing before we decide to push it to production, but the early results have been positive with no visible changes to the user.