迁移到 AndroidX 过程中遇到的各种问题

该博文用来整理开源项目 Android-References 迁移到 AndroidX 过程中遇到的各种问题。

? Android-References 是一个 Android 示例程序项目:包含了 MVP, MVVM, 组件化, ARouter, RxJava, EventBus, ButterKnife, 视频播放, 视频直播, 网络访问, 布局和控件整理等,感性却可以到 Gihub:https://github.com/Shouheng88/Android-references 参考源码。

因为该项目包含了各种 support 包控件,并且各种组件化、架构模式和各种常见的功能一应俱全,因此,比较具有代表性。这里我们使用它来作为一个示例来将我们的项目迁移到 AndroidX。

1、关于 AndroidX

关于 AndroidX,可以参考: Hello world AndroidX

AndroidX 用来统一 Android 中的 support 包,之前我们通过引入 support 包的各个版本来使用支持包,现在我们可以通过使用 AndroidX 来使用支持包。从长远来看这当然是大有好处的,可以避免使用支持包中遇到的版本冲突、升级带来的各种问题。

不过,如果项目完全迁移到 AndroidX 风险还是太大。如果项目紧急的话,引入 AndroidX 成本都有些高,主要是因为一些三方库的原因。虽然一些使用特别多的三方库,比如 Glide 等都已经开始支持 AndroidX。当然,还有一些潜在的问题,比如使用字符串来获取类的 Behavior 等,迁移的时候可能就不会被照顾到。

为了迁移到 AndroidX,Google 给开发者提供了一个工具:在 AS 的 Refactor 中提供了一项 Migrate to AndroidX 的选项。但选择了迁移之后,出现一些问题还需要开发者自己手动解决。

2、着手迁移

2.1 第一个问题:Execution failed for task ‘:app:transformClassesWithMultidexlistForAlphaDebug’

这里我们迁移之后在 build 的时候出现了标题的问题:

* What went wrong:
Execution failed for task ':app:transformClassesWithMultidexlistForAlphaDebug'.
> com.android.build.api.transform.TransformException: Error while generating the main dex list.

显然是将 class 转换成 dex 的过程中出现了一些问题,不过只是上面的这行日志我们无法定位问题。所以,我们需要让 gradle 输出更多的错误信息,于是我们执行:

	gradlew build --stacktrace

来让 Gradle 输出错误栈信息:

Caused by: com.android.builder.multidex.D8MainDexList$MainDexListException: com.android.tools.r8.errors.CompilationError: Program type already present: com.a
libaba.android.arouter.routes.ARouter$$Group$$library
        at com.android.builder.multidex.D8MainDexList.generate(D8MainDexList.java:87)
        at com.android.build.gradle.internal.transforms.D8MainDexListTransform.transform(D8MainDexListTransform.kt:131)
        ... 54 more

显然是 ARouter$$Group$$library 类的问题,我们使用 Ctrl+N 来搜索这个类,发现出现了两个同样的类。这个类是使用阿里的 ARouter 的时候在编译期间生成的:

在这里插入图片描述

按照上面的错误提示,该类同时出现在了我们的两个模块 librarieslayout 下面,因而类冲突了。所以,接下来的问题就是要发现为什么会出现类冲突。

经过一层层排查发现是一个地方写错了:

在这里插入图片描述

这个是 layout 模块下面的冲突的类,我们发现它的路由地址是 /library/swipe_back,所以因为路由的地址是 library 的原因它在 layout 的模块下面生成了 ARouter$$Group$$Library。按照正确的写法它应该是出现在 layout 模块下面,并且路由的地址是 /layout/swipe_back,那样就应该被生成到 ARouter$$Group$$Layout 下面,就不会多出一个类 ARouter$$Group$$Library 了。

虽然,最终问题的原因很简单,但是我们看到,发现问题的过程中需要自己有思路的去排查,而不是除了问题立刻 Google 或者 SOF。

2.2 android.view.InflateException: Binary XML file line #14: Error inflating class

修改了上面的问题之后,我们的程序可以编译并且安装了。

然后,我们又遇到下面的问题:

android.view.InflateException: Binary XML file line #14: Error inflating class

这种问题比较常见,是 XML 的某个地方写错了,经过排查发现有一行代码,当我们为控件添加 Behavior 的时候使用了字符串形式的类名。在迁移的时候没有被照顾到:

在这里插入图片描述

事实上在 Google 的新的 material 包下面的 values.xml 文件中定义了一些 Behavior,新的包中这些字符串的值已经被替换过。但是像我们上面的这种情况,因为使用的是字符串而不是引用的资源,所以就没有被替换过去。因此,引用非自定义的 Behavior 的时候需要注意使用字符串资源进行引用而不是使用字符串:

在这里插入图片描述

2.3 android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton

这里的类 Support28Activity 用来整理原来的 support-28 包里面的一些控件,迁移之后页面打开的时候立即崩溃。然后留下了一地鸡毛(异常):

 java.lang.RuntimeException: Unable to start activity ComponentInfo{me.shouheng.references/me.shouheng.layout.view.support28.Support28Activity}: android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton

我们尝试在程序中寻找 MaterialButton,发现确实能够找到这个类,但这里加载失败是什么原因呢?

于是我们继续查看输出的错误日志,从这里我们获取到了更多的信息。

    Process: me.shouheng.references, PID: 22961
    java.lang.RuntimeException: Unable to start activity ComponentInfo{me.shouheng.references/me.shouheng.layout.view.support28.Support28Activity}: android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3037)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.a
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值