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」按钮。先做三件事:
- 备份项目——我用 Git 分支,万一翻车还能回滚
- 升级 Gradle 和 AGP——AndroidX 需要 Gradle 4.6+ 和 AGP 3.2+
- 检查第三方库——确认你用的所有库都支持 AndroidX
| 检查项 | 要求 | 备注 |
|---|---|---|
| Gradle 版本 | ≥ 4.6 | 建议用 5.0 以上 |
| Android Gradle Plugin | ≥ 3.2.0 | 3.4.0 之后更稳定 |
| compileSdkVersion | ≥ 28 | 推荐 29 或 30 |
| 第三方库 | 全部支持 AndroidX | 去 GitHub 看版本号 |
我曾经在一个项目里直接点一键迁移,结果第三方库不支持,编译报了几十个错。后来老老实实先升级库版本,再迁移。
4.3 两种迁移方式对比
Android Studio 提供了两种迁移方式。我两种都试过,给你说说区别:
- 自动迁移(Refactor → Migrate to AndroidX):AS 帮你改包名、改依赖,快是快,但容易漏掉一些动态引用的地方
- 手动迁移:自己改 build.gradle 里的依赖声明,然后全局替换 import 语句。麻烦但可控
我个人推荐先自动迁移,再手动检查。自动迁移能搞定 80% 的替换,剩下的细节点你心里有数就行。
4.4 常用依赖对照表
迁移时最烦的就是不知道新的 artifact 叫什么。我整理了一张常用对照表:
| Support Library | AndroidX 对应 | 说明 |
|---|---|---|
| com.android.support:appcompat-v7 | androidx.appcompat:appcompat | 最常用,必改 |
| com.android.support:recyclerview-v7 | androidx.recyclerview:recyclerview | 包名变了,API 不变 |
| com.android.support:cardview-v7 | androidx.cardview:cardview | 注意构造函数可能有变化 |
| com.android.support:design | com.google.android.material:material | Migration Guide 里专门提过 |
| com.android.support:support-v4 | androidx.legacy:legacy-support-v4 | 尽量拆成具体模块 |
| com.android.support:multidex | androidx.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 这些组件的页面
你想想看,迁移这事儿本质上是换汤不换药。代码逻辑没变,只是包名变了。但就是这些细小的变化,能让你折腾一整天。嗯,按我上面说的步骤来,至少能少踩一半的坑。