摘要:如何升级到androidX,androidX中一些类库的变化
升级到androidX
简介
AndroidX是android.support.xxx
整理后的产物。是由于之前的support包过于混乱。
迁移步骤
修改当前项目的gradle.properties
1 | #表示当前项目启用 AndroidX |
如何迁移
在AndroidStudio3.2+版本中:Refactor–》Migrate to AndroidX(注意要提前备份)
迁移后续
手动修改错误包名
部分控件的包名/路径名转换有问题,需要手动调整(包括xml
布局文件和.java
或.kt
文件)
如:ViewPager、RecyclerView等,包名变成android.core.weight.xxxx
这是错误的包名,需要手动修改。
修复DataBinding中的错误(重名id错误)
去除attr.xml中重复的属性名称
Glide 中的注解不兼容AndroidX
规范包名(即文件夹名)
修改未自动迁移的三方库
莫名问题的解决
修复项目默认启用 androidx 的情况
AndroidX与Jetpack
- Jetpack是一套库、工具和指南;AndroidX是Android团队用于在Jetpack中开发、测试、打包和发布库以及对其进行版本控制的开源项目。
- Jetpack组件是AndroidX库的一部分。
- AndroidX可完全取代支持库(
android.support*
),不仅提供同等的功能,而且提供了新的库。
官方链接推荐
旧版本包与AndroidX对照表
旧包 | AndroidX |
---|---|
android.arch.core:common | androidx.arch.core:core-common:2.0.0-rc01 |
android.arch.core:core | androidx.arch.core:core:2.0.0-rc01 |
android.arch.core:core-testing | androidx.arch.core:core-testing:2.0.0-rc01 |
android.arch.core:runtime | androidx.arch.core:core-runtime:2.0.0-rc01 |
android.arch.lifecycle:common | androidx.lifecycle:lifecycle-common:2.0.0-rc01 |
android.arch.lifecycle:common-java8 | androidx.lifecycle:lifecycle-common-java8:2.0.0-rc01 |
android.arch.lifecycle:compiler | androidx.lifecycle:lifecycle-compiler:2.0.0-rc01 |
android.arch.lifecycle:extensions | androidx.lifecycle:lifecycle-extensions:2.0.0-rc01 |
android.arch.lifecycle:livedata | androidx.lifecycle:lifecycle-livedata:2.0.0-rc01 |
android.arch.lifecycle:livedata-core | androidx.lifecycle:lifecycle-livedata-core:2.0.0-rc01 |
android.arch.lifecycle:reactivestreams | androidx.lifecycle:lifecycle-reactivestreams:2.0.0-rc01 |
android.arch.lifecycle:runtime | androidx.lifecycle:lifecycle-runtime:2.0.0-rc01 |
android.arch.lifecycle:viewmodel | androidx.lifecycle:lifecycle-viewmodel:2.0.0-rc01 |
android.arch.paging:common | androidx.paging:paging-common:2.0.0-rc01 |
android.arch.paging:runtime | androidx.paging:paging-runtime:2.0.0-rc01 |
android.arch.paging:rxjava2 | androidx.paging:paging-rxjava2:2.0.0-rc01 |
android.arch.persistence.room:common | androidx.room:room-common:2.0.0-rc01 |
android.arch.persistence.room:compiler | androidx.room:room-compiler:2.0.0-rc01 |
android.arch.persistence.room:guava | androidx.room:room-guava:2.0.0-rc01 |
android.arch.persistence.room:migration | androidx.room:room-migration:2.0.0-rc01 |
android.arch.persistence.room:runtime | androidx.room:room-runtime:2.0.0-rc01 |
android.arch.persistence.room:rxjava2 | androidx.room:room-rxjava2:2.0.0-rc01 |
android.arch.persistence.room:testing | androidx.room:room-testing:2.0.0-rc01 |
android.arch.persistence:db | androidx.sqlite:sqlite:2.0.0-rc01 |
android.arch.persistence:db-framework | androidx.sqlite:sqlite-framework:2.0.0-rc01 |
com.android.support.constraint:constraint-layout | androidx.constraintlayout:constraintlayout:1.1.2 |
com.android.support.constraint:constraint-layout-solver | androidx.constraintlayout:constraintlayout-solver:1.1.2 |
com.android.support.test.espresso.idling:idling-concurrent | androidx.test.espresso.idling:idling-concurrent:3.1.0 |
com.android.support.test.espresso.idling:idling-net | androidx.test.espresso.idling:idling-net:3.1.0 |
com.android.support.test.espresso:espresso-accessibility | androidx.test.espresso:espresso-accessibility:3.1.0 |
com.android.support.test.espresso:espresso-contrib | androidx.test.espresso:espresso-contrib:3.1.0 |
com.android.support.test.espresso:espresso-core | androidx.test.espresso:espresso-core:3.1.0 |
com.android.support.test.espresso:espresso-idling-resource | androidx.test.espresso:espresso-idling-resource:3.1.0 |
com.android.support.test.espresso:espresso-intents | androidx.test.espresso:espresso-intents:3.1.0 |
com.android.support.test.espresso:espresso-remote | androidx.test.espresso:espresso-remote:3.1.0 |
com.android.support.test.espresso:espresso-web | androidx.test.espresso:espresso-web:3.1.0 |
com.android.support.test.janktesthelper:janktesthelper | androidx.test.jank:janktesthelper:1.0.1 |
com.android.support.test.services:test-services | androidx.test:test-services:1.1.0 |
com.android.support.test.uiautomator:uiautomator | androidx.test.uiautomator:uiautomator:2.2.0 |
com.android.support.test:monitor | androidx.test:monitor:1.1.0 |
com.android.support.test:orchestrator | androidx.test:orchestrator:1.1.0 |
com.android.support.test:rules | androidx.test:rules:1.1.0 |
com.android.support.test:runner | androidx.test:runner:1.1.0 |
com.android.support:animated-vector-drawable | androidx.vectordrawable:vectordrawable-animated:1.0.0 |
com.android.support:appcompat-v7 | androidx.appcompat:appcompat:1.2.0 |
com.android.support:asynclayoutinflater | androidx.asynclayoutinflater:asynclayoutinflater:1.0.0 |
com.android.support:car | androidx.car:car:1.0.0-alpha5 |
com.android.support:cardview-v7 | androidx.cardview:cardview:1.0.0 |
com.android.support:collections | androidx.collection:collection:1.0.0 |
com.android.support:coordinatorlayout | androidx.coordinatorlayout:coordinatorlayout:1.0.0 |
com.android.support:cursoradapter | androidx.cursoradapter:cursoradapter:1.0.0 |
com.android.support:customtabs | androidx.browser:browser:1.0.0 |
com.android.support:customview | androidx.customview:customview:1.0.0 |
com.android.support:design | com.google.android.material:material:1.0.0-rc01 |
com.android.support:documentfile | androidx.documentfile:documentfile:1.0.0 |
com.android.support:drawerlayout | androidx.drawerlayout:drawerlayout:1.0.0 |
com.android.support:exifinterface | androidx.exifinterface:exifinterface:1.0.0 |
com.android.support:gridlayout-v7 | androidx.gridlayout:gridlayout:1.0.0 |
com.android.support:heifwriter | androidx.heifwriter:heifwriter:1.0.0 |
com.android.support:interpolator | androidx.interpolator:interpolator:1.0.0 |
com.android.support:leanback-v17 | androidx.leanback:leanback:1.0.0 |
com.android.support:loader | androidx.loader:loader:1.0.0 |
com.android.support:localbroadcastmanager | androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 |
com.android.support:media2 | androidx.media2:media2:1.0.0-alpha03 |
com.android.support:media2-exoplayer | androidx.media2:media2-exoplayer:1.0.0-alpha01 |
com.android.support:mediarouter-v7 | androidx.mediarouter:mediarouter:1.0.0 |
com.android.support:multidex | androidx.multidex:multidex:2.0.0 |
com.android.support:multidex-instrumentation | androidx.multidex:multidex-instrumentation:2.0.0 |
com.android.support:palette-v7 | androidx.palette:palette:1.0.0 |
com.android.support:percent | androidx.percentlayout:percentlayout:1.0.0 |
com.android.support:preference-leanback-v17 | androidx.leanback:leanback-preference:1.0.0 |
com.android.support:preference-v14 | androidx.legacy:legacy-preference-v14:1.0.0 |
com.android.support:preference-v7 | androidx.preference:preference:1.0.0 |
com.android.support:print | androidx.print:print:1.0.0 |
com.android.support:recommendation | androidx.recommendation:recommendation:1.0.0 |
com.android.support:recyclerview-selection | androidx.recyclerview:recyclerview-selection:1.0.0 |
com.android.support:recyclerview-v7 | androidx.recyclerview:recyclerview:1.0.0 |
com.android.support:slices-builders | androidx.slice:slice-builders:1.0.0 |
com.android.support:slices-core | androidx.slice:slice-core:1.0.0 |
com.android.support:slices-view | androidx.slice:slice-view:1.0.0 |
com.android.support:slidingpanelayout | androidx.slidingpanelayout:slidingpanelayout:1.0.0 |
com.android.support:support-annotations | androidx.annotation:annotation:1.0.0 |
com.android.support:support-compat | androidx.core:core:1.0.0 |
com.android.support:support-content | androidx.contentpager:contentpager:1.0.0 |
com.android.support:support-core-ui | androidx.legacy:legacy-support-core-ui:1.0.0 |
com.android.support:support-core-utils | androidx.legacy:legacy-support-core-utils:1.0.0 |
com.android.support:support-dynamic-animation | androidx.dynamicanimation:dynamicanimation:1.0.0 |
com.android.support:support-emoji | androidx.emoji:emoji:1.0.0 |
com.android.support:support-emoji-appcompat | androidx.emoji:emoji-appcompat:1.0.0 |
com.android.support:support-emoji-bundled | androidx.emoji:emoji-bundled:1.0.0 |
com.android.support:support-fragment | androidx.fragment:fragment:1.0.0 |
com.android.support:support-media-compat | androidx.media:media:1.0.0 |
com.android.support:support-tv-provider | androidx.tvprovider:tvprovider:1.0.0 |
com.android.support:support-v13 | androidx.legacy:legacy-support-v13:1.0.0 |
com.android.support:support-v4 | androidx.legacy:legacy-support-v4:1.0.0 |
com.android.support:support-vector-drawable | androidx.vectordrawable:vectordrawable:1.0.0 |
com.android.support:swiperefreshlayout | androidx.swiperefreshlayout:swiperefreshlayout:1.0.0 |
com.android.support:textclassifier | androidx.textclassifier:textclassifier:1.0.0 |
com.android.support:transition | androidx.transition:transition:1.0.0 |
com.android.support:versionedparcelable | androidx.versionedparcelable:versionedparcelable:1.0.0 |
com.android.support:viewpager | androidx.viewpager:viewpager:1.0.0 |
com.android.support:wear | androidx.wear:wear:1.0.0 |
com.android.support:webkit | androidx.webkit:webkit:1.0.0 |
Annotations API
AndroidX踩坑指南
转成AndroidX的原因
- 主动原因:Support 包从 API 28 (Android 9.0)已经弃更,取而代之的是谷歌新推出的 AndroidX 的包。
- 被动原因:现在一些第三方库都是直接依赖 AndroidX 包,由于谷歌限制 Support 包和 AndroidX 包不能共存的机制,导致我们无法直接依赖第三方库的最新版本,例如某个框架的最新版的依赖就是基于 AndroidX 包,这样就导致我们只能去依赖旧版的框架,无法使用最新框架。
转成AndroidX的步骤
Android Studio:Refactor》Migrate to Android X…
Studio帮我们做了什么事
- 自动替换导入类和xml中的View包名
1 | import android.support.v7.app.AppCompatActivity; |
1 | <android.support.v7.widget.RecyclerView /> |
- Support 远程依赖变化
1 | implementation 'com.android.support:appcompat-v7:28.0.0' |
1 | implementation 'androidx.appcompat:appcompat:1.0.0' |
- gradle.properties 配置变化
1 | # 表示使用 AndroidX |
踩坑
坑一:找不到约束布局
这个因为 AndroidX 包中并没有依赖 ConstraintLayout 库,只需要手动加入依赖即可
1
implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
坑二:导包报错
- 部分导包报错,只需要手动更换引用的包名即可,这里不指定包名 Studio 自动会帮我们导入默认的
坑三:第三方库的坑
虽然在这次转换的过程中没有出现过这种异常,但是根据以往的经验,这两个第三方库很可能会导致编译不通过
1
2
3
4
5implementation 'com.jakewharton:butterknife:9.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0'
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'这个是因为这两个库的旧版本依赖 Support 包导致的,所以解决的方式是将这两个库升级到最新版本即可
1
2
3
4implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
坑四:替换不干净
Studio 只能帮我们替换显式调用的包名,而不能帮我们替换隐式调用的包名,例如通过反射填写的包名,混淆规则等等
1
2
3
4Class.forName("android.support.design.widget.Snackbar");
Class.forName("android.support.design.widget.BottomSheetDialog");
-keep class android.support.**{*;}解决的方式也很简单,在项目中全局搜索
android.support
关键字眼,然后手动进行替换
坑五:Fragment 封装
升级 AndroidX 后,切换 Fragment 出现
NullPointerException:androidx.fragment.app.FragmentManagerImpl.isDestroyed()
异常,经过排查是 Fragment 基类中存在这些反射的代码导致的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public abstract class BaseFragment extends Fragment {
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}这些代码是为了解决 Fragment 相互切换出现崩溃的 Bug,而这个 Bug 在 AndroidX 的版本已经被官方修复了,所以解决方案是删除掉这些代码即可。
如果你对这个 Bug 感兴趣,可以点击此处了解:Getting the error “Java.lang.IllegalStateException Activity has been destroyed” when using tabs with ViewPager
常见误区:FileProvider
关于 FileProvider 的清单注册,没转 AndroidX 之前是这样子的
1
2
3
4
5
6
7
8
9
10<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>转成 AndroidX 之后的是这样子的
1
2
3
4
5
6
7
8
9
10<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
其中的android.support.FILE_PROVIDER_PATHS
不能自己改成androidX.。。。
Jetpack问题
“ViewDataBinding.getRoot() on a null object reference”
组件化开发的时候,报上面这个问题。
解决:
- 宿主src的包名与组件下src的包名不能一样
- 宿主对组件要用implementation,而不是runtime
…DataBinderMapperImpl.java:9: 错误: 找不到符号
1 | D:\code\MyTests\MVVMDemo\app\build\generated\ap_generated_sources\debug\out\com\ab\mvvmdemo\DataBinderMapperImpl.java:9: 错误: 找不到符号 |
解决:十有八九是xml报错了。“排除法”排查xml的错误
ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()).create(UserViewModel.class); 报 RuntimeException
解决:在此处断点,跟进去看具体报错【最后发现是关联的其他的实例需要在MyApplication中获取。而MyApplication没有在清单中进行实例化导致的】