原标题:The Reality of Migrating to AndroidX
原文地址:https://blog.danlew.net/2018/11/14/the-reality-of-migrating-to-androidx
原文作者:Dan Lew
作者推特:https://twitter.com/danlew42
今年,谷歌将Android库的支持重新命名为Android Jetpack(又称AndroidX)。
与开发人员特别相关的是他们如何重新打包所有库。它们的 maven坐标 不仅发生了变化,而且每个类的包名也发生了变化。例如,android.support.v7.app.AppCompatActivity
现在androidx.appcompat.app.AppCompatActivity
。
旧的人工产品和包装名称是混乱不清的,所以从长远来看,这是一个伟大的举动。但是,在短期内,升级需要对代码库进行大量更改。
从理论上讲,这种迁移应该像在Android Studio中运行“Migrate to AndroidX”工具一样简单。如果这适用于您的应用程序,那太棒了!现在停止阅读这篇文章!
不幸的是,我们发现它比那更麻烦。以下是我们实际完成迁移的方式。
在开始调整迁移到AndroidX的想法之前,您应该了解所有当前支持库工件的最新版本。这样,从旧工件到新工件的跳跃应该只需要更改包名称。
在大多数情况下,这意味着在支持库的v28.0.0版本上。但是,一些支持库使用其他版本控制方案:例如,我们必须将Android KTX升级到v0.3,将Room持久性库升级到v1.1.1。
提前做好此准备工作非常适合揭示需要较旧版本支持库且必须更新的代码库部分。
例如,我们发现SqlDelight需要旧版本的Room持久性库。最后,我们要求(并收到)一个版本的SqlDelight,通过支持最新的持久性库(转发,Square!)使转换变得更容易。
一旦您的依赖关系连续出现,下一步就是尝试Android Studio的“迁移到AndroidX”工具。不幸的是,它以多种方式失败了我们的代码库:
修复maven坐标非常简单,要么在Google的存储库中查找最新版本,要么使用gradle-versions-plugin自动检测最新的工件。
更艰巨的任务是确保我们实际转换了所有包名。 幸运的是,Google提供了一个csv文件,映射旧的包名称,我们在一个小脚本中使用它来转换代码库。 这个脚本需要几分钟才能运行,但它允许我们始终将代码库转换为新的包名。
不幸的是,类映射CSV不完整。例如,它缺少大多数设计库类映射(即android.support.design.widget
中的类)。我不得不在我自己的CSV中添加几行以使其转换所有内容。
jetifier 是一个方便的工具,可以在构建时自动将依赖项迁移到AndroidX。如果没有它,在迁移之前,您需要使用每个依赖项来拥有AndroidX版本,这可能不会发生一段时间。
需要注意的是一个重要的限制:jetifier仅适用于打包的工件。 它不适用于您希望自己更新的源代码。
不幸的是,您的应用程序可能包含既不是打包工件也不是您控制的源代码的代码:生成的代码。你既不编写也不维护它,但它被编译为好像它是你自己的源代码。
如果生成的代码引用旧工件,则可能会遇到麻烦。 以Butter Knife为例。 它生成包含支持注释的引用的类(例如android.support.annotation.UiThread
)。 这些导入无法满足AndroidX(因为它是源代码),所以你会得到编译器错误。
对于生成的代码,您必须更新您的依赖项,以便生成与AndroidX兼容的代码。
对于我们来说,这是一个问题,有两个代码生成器 - Butter Knife和SqlDelight。值得庆幸的是,两者都有支持AndroidX的版本(非常感谢Square制作AndroidX友好的工件)。
考虑到上述所有情况,您应该感到惊讶,因为我花了相当多的时间将我们的代码库升级到AndroidX。
由于团队中的其他开发人员仍在不断更改代码库,所以花费的时间导致了自己的问题。 他们对修改后的import语句所做的每一次更改都会导致与我正在进行的AndroidX分支的痛苦合并冲突。 手工维护那个分支将是一个巨大的痛苦。
这个问题是我编写迁移脚本的第二个原因。每当我将我的AndroidX分支重新命名为最新的master时,我只需重新运行脚本而不是尝试处理合并。 我用这种方式挽救了一大堆努力。
支持库工件已被弃用,所有未来的开发都将进入AndroidX,因此无法避免此迁移。但是,希望这些技巧能为您提供更清晰的过渡路径。