AndroidX 迁移

AndroidX介绍

按照官方文档说明 AndroidX 是对 android.support.xxx 包的整理后产物。由于之前的 support 包过于混乱,所以,Google 推出了AndroidX。

由于在后续版本中,会逐步放弃对 support 的升级和维护,所以,我们必须迁移到 AndroidX。

注意:我们建议在单独的分支中执行迁移。此外,还应设法避免在执行迁移时重构代码。

编译环境

AndroidStudio3.2及以上

targetSdkVersion版本为28及以上

gradle要3.2.0及以上

迁移步骤

1. 修改gradle.properties

1
2
android.useAndroidX=true
android.enableJetifier=true

android.useAndroidX=true 表示启用 androidx

android.enableJetifier=true 表示将依赖包也迁移到androidx 。如果取值为false,表示不迁移依赖包到androidx,但在使用依赖包中的内容时可能会出现问题,如果项目中没有使用任何三方依赖,可以设置为false。

2. 更新依赖

将app依赖的三方库尽量都升级到支持androidx的版本,这样可以避免在迁移中发生冲突。

3. 在AS中执行Refactor->Migrate to AndroidX

在执行该操作时会提醒我们是否将当前项目打包备份。如果你提前已经做好了备份,可以忽略;如果没有备份,则先备份。

当然一般情况,这一步执行完以后还有很多support库的引用没有更换为androidx。

Activity/Fragment/XML(包括涉及到使用support包的工具类等),原来引用support包中的类,在Migrate后并不能完全对应,会有很多错误(方便还是有代价的,通往幸福的路总是充满坎坷),所以需要改成对应的androidX中的类引用。

注:可以手动迁移,除了麻烦点并没有太大风险。

4. 混淆更改

1
2
3
4
5
6
7
8
9
10
11
12
# androidx
-keep class com.google.android.material.** {*;}
-keep class androidx.** {*;}
-keep public class * extends androidx.**
-keep interface androidx.** {*;}
-keep @androidx.annotation.Keep class *
-keepclassmembers class * {
@androidx.annotation.Keep *;
}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
-dontwarn androidx.**

5. 统一版本号

一般来说弄完上面一步就可以解决问题了。但是也有不一般的情况,就是androidX的版本不一致导致的问题 大概报错提示可以看到androidx.core:core:1.1.0 ... androidx.core:core:1.0.0 之类的,就说明是版本不一致了

这时就要固定版本,让插件的版本也保持一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// androidx version: 固定版本
resolutionStrategy {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'androidx.core') {
details.useVersion "1.3.1"
}
if (details.requested.group == 'androidx.lifecycle') {
details.useVersion "2.0.0"
}
if (details.requested.group == 'androidx.versionedparcelable') {
details.useVersion "1.1.0"
}
if (details.requested.group == 'androidx.fragment') {
details.useVersion "1.1.0"
}
if (details.requested.group == 'androidx.appcompat') {
details.useVersion "1.2.0"
}
}
}

版本库统一管理

由于升级插件的原因,原来的使用gradle全局管理依赖会直接被替换,比如以前引用是这样的

1
implementation rootProject.ext.dependencies.libSupportAppcompatV7

被替换之后就是这样了

1
implementation "androidx.appcompat:appcompat:1.0.0"

为了我们方便管理我们需要手动更改一下,然后根据我们的需要在对应的引入文件替换。

1
2
3
4
5
6
7
8
9
10
11
12
//androidx
libXAnnotation : "androidx.annotation:annotation:${ANDROIDX_LIB_VERSION}",
libXAppcompat : "androidx.appcompat:appcompat:${ANDROIDX_LIB_VERSION}",
libXRecyclerview : "androidx.recyclerview:recyclerview:${ANDROIDX_LIB_VERSION}",
libXCoreKtx : "androidx.core:core-ktx:$ANDROIDX_LIB_VERSION",
libXFragmentKtx : "androidx.fragment:fragment-ktx:$ANDROIDX_LIB_VERSION",
libXSwiperefreshlayout : "androidx.swiperefreshlayout:swiperefreshlayout:$ANDROIDX_LIB_VERSION",
libXMaterial : "com.google.android.material:material:${ANDROIDX_LIB_VERSION}",//替代com.android.support:design

libXMultidex : 'androidx.multidex:multidex:2.0.0',
libConstraintLayout : 'androidx.constraintlayout:constraintlayout:1.1.3',//暂时有需要用到
libXCardView : 'androidx.cardview:cardview:1.0.0',//替代com.android.support:cardview-v7

具体查看官方组建映射对照表,更换之后编译解决报错即可,主要是一些三方依赖造成依赖冲突的问题,可以类似第一步强制指定版本号。

修改未自动迁移的三方库

虽然我们从 gradle 中配置了迁移三方库的参数,但是,由于三方库的版本更新问题,也可能会迁移失败。在三方库迁移失败时,如果使用了数据绑定,通常会报如下错误:

碰到上述错误之后,我们可以按下列步骤处理:

1、在 gradle 文件中,将可升级的三方库升级(通常情况下,可升级的三方库会有黄色提示)

2、如果 gradle 中可升级的库都升级之后依旧报上述错误,那么,可以新建一个项目,然后将 gradle 中的依赖库逐个拷贝到新项目中,每拷贝一个编译一次,这样可以确认是哪个三方库有问题。(实际操作时可以使用二分法的方式进行,每次拷贝一半的依赖库,然后编译)。然后就可以有针对性的处理了

解决AndroidX与第三方库依赖冲突

如果你的项目引用了AndroidX 但是现在起GitHub上很多的第三方库,引用的还是Android support依赖。这样就会产生类似于Error: Program type already present: androidx.legacy.app.ActionBarDrawerToggle$Delegate的错误提示。这个表示AndroidX 与 Android support冲突。

解决方案:

implementation(‘第三方库的依赖’) { exclude group: ‘com.android.support’ }

其它坑点

1. 注解处理器冲突

运行报错发现是因为项目中有用到butterknife,使用的版本没有androidX支持,更新到最新的10.1.0。(Glide、Dagger之类的也会出现)

2. androidX严格检查引起的问题

  • AndroidManifest.XML文件报错(注释检查)

  • 修复 DataBinding 中的错误(重名id错误)

  • 去除 attr.xml 中重复的属性名称(自定义控件中属性与系统已有属性重名)

  • 包名不规范(包名以小写或者“_”的形式,不要用大写等)

3. 莫名问题的解决

迁移过程中如果爆出一些 android 包本身或者其他莫名其妙的问题时,先去 xml 布局文件 或 .java 文件中找一下,是否有继续引用 xxx.support.xxx 的情况,如果有,记得替换成 androidx.xxx.xxx 包下的对应控件。( xxx 泛指任意内容)

参考资料

1、官方迁移指南

2、AndroidX终极迁移指南

3、androidx升级

4、你好,androidX!

5、是时候迁移至 AndroidX 了

6、androidX库版本