4. AndroidX 迁移实战与注意事项归纳总结

AndroidX 这事儿,说白了就是 Google 把 Support Library 重新整理了一遍。名字换了,包名也换了,但核心逻辑没变。我当年接手一个老项目,里面还是 android.support.v4 那套,光迁移就折腾了两天。嗯,今天咱们就把这块讲透。

4.1 为什么要迁移到 AndroidX

你可能觉得 Support Library 用得好好的,干嘛要动?其实原因很简单:

  • Support Library 不更新了:Google 在 28.0.0 之后就不再维护 Support Library,所有新功能只给 AndroidX
  • 包名冲突:android.support.* 和 androidx.* 不能共存,你想用新出的 Material 组件?必须先迁移
  • 版本统一:AndroidX 采用语义化版本控制,再也不会有「怎么 support-v4 和 appcompat 版本不一致」的问题

我个人习惯:新项目直接启用 AndroidX,旧项目如果还在维护,建议尽早迁移。拖得越久,第三方库的兼容成本越高。

4.2 迁移前的准备工作

别急着点那个「Migrate to AndroidX」按钮。先做三件事:

  1. 备份项目——我用 Git 分支,万一翻车还能回滚
  2. 升级 Gradle 和 AGP——AndroidX 需要 Gradle 4.6+ 和 AGP 3.2+
  3. 检查第三方库——确认你用的所有库都支持 AndroidX
检查项要求备注
Gradle 版本≥ 4.6建议用 5.0 以上
Android Gradle Plugin≥ 3.2.03.4.0 之后更稳定
compileSdkVersion≥ 28推荐 29 或 30
第三方库全部支持 AndroidX去 GitHub 看版本号

我曾经在一个项目里直接点一键迁移,结果第三方库不支持,编译报了几十个错。后来老老实实先升级库版本,再迁移。

4.3 两种迁移方式对比

Android Studio 提供了两种迁移方式。我两种都试过,给你说说区别:

  • 自动迁移(Refactor → Migrate to AndroidX):AS 帮你改包名、改依赖,快是快,但容易漏掉一些动态引用的地方
  • 手动迁移:自己改 build.gradle 里的依赖声明,然后全局替换 import 语句。麻烦但可控

我个人推荐先自动迁移,再手动检查。自动迁移能搞定 80% 的替换,剩下的细节点你心里有数就行。

AndroidX 迁移决策流程 开始迁移评估 检查 Gradle 版本 通过? 检查第三方库兼容 升级 Gradle / AGP 兼容? 执行自动 + 手动迁移 更换/升级库

4.4 常用依赖对照表

迁移时最烦的就是不知道新的 artifact 叫什么。我整理了一张常用对照表:

Support LibraryAndroidX 对应说明
com.android.support:appcompat-v7androidx.appcompat:appcompat最常用,必改
com.android.support:recyclerview-v7androidx.recyclerview:recyclerview包名变了,API 不变
com.android.support:cardview-v7androidx.cardview:cardview注意构造函数可能有变化
com.android.support:designcom.google.android.material:materialMigration Guide 里专门提过
com.android.support:support-v4androidx.legacy:legacy-support-v4尽量拆成具体模块
com.android.support:multidexandroidx.multidex:multidex配置方式不变

小技巧:如果某个库找不到对应版本,去 AndroidX Artifact Mappings 页面查官方映射表。

4.5 迁移过程中的坑

说几个我踩过的坑,你遇到的时候心里有数:

4.5.1 R 类引用问题

迁移后 R 类的路径变了。以前是 com.example.R,现在可能变成 com.example.databinding.R 或者 com.example.R 不变。我建议全局搜索 import android.support.,把 R 类的导包全清掉,让 AS 自动导。


// 迁移前
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;

// 迁移后
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

4.5.2 Fragment 的 getActivity() 返回 null

这个问题在 Support Library 时代就有,但 AndroidX 的 Fragment 生命周期更严格。如果你在 onActivityCreated() 之后还调用 getActivity(),很可能返回 null。解决办法是改用 requireActivity(),它能确保 Activity 不为空时再返回。

注意:requireActivity() 只能在 Fragment 附加到 Activity 之后调用,否则会抛 IllegalStateException。

4.5.3 资源命名冲突

AndroidX 引入了新的资源命名空间。如果你的项目里有和 AndroidX 同名的资源文件(比如 res/values/colors.xml 里定义了 primary_color),可能会被覆盖。我建议把自定义资源加上前缀,比如 app_primary_color。

4.6 迁移后的验证

迁移完别急着提交。先跑一遍:

  • 编译通过——这是底线
  • 运行所有单元测试——我吃过亏,有个 Fragment 的测试用例全挂了,因为 Mockito 版本不兼容 AndroidX
  • 手动测试关键页面——特别是用了 RecyclerView、ViewPager 这些组件的页面

你想想看,迁移这事儿本质上是换汤不换药。代码逻辑没变,只是包名变了。但就是这些细小的变化,能让你折腾一整天。嗯,按我上面说的步骤来,至少能少踩一半的坑。