AndroidX介绍
按照官方文档说明 AndroidX 是对 android.support.xxx 包的整理后产物。由于之前的 support 包过于混乱,所以,Google 推出了AndroidX。
由于在后续版本中,会逐步放弃对 support 的升级和维护,所以,我们必须迁移到 AndroidX。
注意:我们建议在单独的分支中执行迁移。此外,还应设法避免在执行迁移时重构代码。
编译环境
AndroidStudio3.2及以上
targetSdkVersion版本为28及以上
gradle要3.2.0及以上
迁移步骤
1. 修改gradle.properties
1 | android.useAndroidX=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 | # 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、官方迁移指南