项目重构——kotlin升级的探索与实践

前言

先说下我们公司的目前kotlin和gradle版本

kotlin版本 gradle插件版本 gradle版本 minSdkVersion targetSdkVersion
1.3.72 4.0.2 6.7.1 21 33

我们升级后的目标是

kotlin版本 gradle插件版本 gradle版本 minSdkVersion targetSdkVersion
1.6.10 4.1.1 6.7.1 21 33

为什么升级和升级理由就不阐述了,直接上正餐。

gradle插件版本与gradle版本

插件版本 所需的最低Gradle 版本
8.1 8.0
8.0 8.0
7.4 7.5
7.3 7.4
7.2 7.3.3
7.1 7.2
7.0 7.0
4.2.0+ 6.7.1
4.0.0+ 6.1.1+

实践

首先我们直接上手,对gradle插件和kotlin进行升级

koltin 复制代码
ext.kotlin_version = '1.6.10'
kotlin 复制代码
dependencies {
    classpath 'com.android.tools.build:gradle:4.1.1'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

直接点击同步我们遇到了第一个问题

异常一:Unable to get provider androidx.startup.InitializationProvider: androidx.startup.StartupException: java. lang.ClassNotFoundException:androidx.emoji2.text.EmojiCompatInitializer

第一反应有点懵,我都没添加过androidx.emobji2,这是啥玩意?多亏我在看过的寥寥无几的文章中,恰巧瞟了一眼关于emobji2的文章,这玩意添加依赖应该就可以嘞

kotlin 复制代码
def emojiVersion = "1.3.0"
implementation "androidx.emoji2:emoji2:$emojiVersion"
implementation "androidx.emoji2:emoji2-views:$emojiVersion"

同步一下,不报这个错了(不愧是我😏),然后就报了第二个错误

异常二:Unable to get provider androidx.startup.InitializationProvider: androidx.startup.StartupException: java. lang.ClassNotFoundException:com.huawei.agconnect.core.provider.AGConnectInitializeProvider
  • 看了源码,这是华为自带的AGConnectInitializeProvider,然后打包的时候找不到,上网查大部分都是说要开启multixDex分包
  • 但是我的minSdkVersion是21(Android 5.0)默认是开启分包的,完全不需要配置multiDex相关配置
  • 我看到androidx.startup.InitializationProvider,就感觉这个玩意有鬼,于是就找了官方网址:developer.android.google.cn/jetpack/and...

使用

  1. app->build.gradle中添加相关依赖
kotlin 复制代码
implementation "androidx.startup:startup-runtime:1.2.0-alpha02"
  1. app->build.gradle中添加androidx.startup.InitializationProvider
kotlin 复制代码
<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
</provider>
  1. app->build.gradle中移除报错的AGConnectInitializeProvider,直接拷贝源码,然后添加tools:node="remove"即可。此方法会停用AGConnectInitializeProvider的自动初始化功能
kotlin 复制代码
<provider
    android:name="com.huawei.agconnect.core.provider.AGConnectInitializeProvider"
    android:authorities="${applicationId}.AGCInitializeProvider"
    android:exported="false"
    tools:node="remove" />
  1. 之后创建一个类AGConnectInitializeProviderInitializer继承
  • onCreate中进行初始化
  • dependencies:表示你需要的依赖库,不依赖其他库,可直接返回空列表
kotlin 复制代码
class AGConnectInitializeProviderInitializer:Initializer<Unit> {
    override fun create(context: Context) {
        AGConnectInstance.initialize(context)
    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
       return mutableListOf()
    }
}
  1. 调用组件初始化程序,Application中进行初始化
java 复制代码
AppInitializer.getInstance(this).initializeComponent(InitProviderInitializer.class);

重新运行项目,我们会发现AutoSize这个库也会报上面的错误,我们继续按上面步骤走就好,只是第五步的时候,我们添加一个统一管理类InitProviderInitializer 修改后的代码如下

kotlin 复制代码
class InitProviderInitializer : Initializer<Unit> {
    override fun create(context: Context) {

    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        return mutableListOf(
            AutoSizeInitProviderInitializer::class.java,
            AGConnectInitializeProviderInitializer::class.java
        )
    }
}

AutoSizeInitProviderInitializer的代码如下

kotlin 复制代码
class AutoSizeInitProviderInitializer: Initializer<Unit> {
    override fun create(context: Context) {
        AutoSize.checkAndInit(context.applicationContext as Application)
    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        return mutableListOf()
    }
}

继续运行,我们发现它又报下面的错 阿哈?我明明没用到呀,他为什么报错呢?我总感觉Google在给我挖坑(嗯,一定是),既然还是androidx.startup错误,那就继续

kotlin 复制代码
class InitProviderInitializer : Initializer<Unit> {
    override fun create(context: Context) {

    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        return mutableListOf(
            AutoSizeInitProviderInitializer::class.java,
            AGConnectInitializeProviderInitializer::class.java,
            EmojiCompatInitializer::class.java
        )
    }
}

终于呀,不报androidx.startup相关错误,但是,他还是报错😭。

异常三:com.mob.MobProvider: iava.lang.ClassNotFoundException: Didn't find class "com.mob.MobProvider"
  • 我对了好几遍shareSDK官方文档,确定了好几遍,得到一个结论:我写的就是复制粘贴的,没毛病,但是就是报错。
  • 我看到有的文章说是因为你项目中有多个版本,移除某个依赖,gradle.clean下重启一下(实测无效,浪费大把时间)
  • 我盲测既然以前没问题,现在有问题,那就是gradle配置某项有问题,于是我找到了gradle.properties,撬开了它的天灵盖
kotlin 复制代码
android.useDeprecatedNdk=true
android.enableD8=true
android.useDexArchive=true
android.enableD8.desugaring=false
android.enableAapt2=true

android.enableD8=true

  • 启用D8 Dex编译器,这是Android Gradle插件3.0及更高版本的默认选项,用于更高效地处理Dex编译

android.useDexArchive=true

  • 启用Dex归档,以提高构建和应用启动性能。这是一个有助于加快应用加载速度的优化

android.enableAapt2=tru

  • 启用AAPT2资源打包工具,它提供更快的资源处理速度和更好的错误报告。AAPT2是默认启用的

android.enableD8.desugaring=false

  • 用于控制是否启用D8编译器的Desugaring功能。
  • Desugaring是一种处理Java 8+语言特性的技术,使其能够在Android版本低于8.0的设备上运行。Android 8.0(API级别26)引入了对Java 8语言特性的原生支持,但在此之前的Android版本中,某些新的语言特性需要通过Desugaring来实现兼容性。

一句话就是:建议保留此配置设置(android.enableD8.desugaring=true)。删掉此配置之后,重新运行,发现正常运行了。

总结

在kotlin和gradle升级过程中,我们会发现有引入一些新的东西和对gradle依赖的更新,以后大家还是要有机会经常去更新自己公司项目的库,防止一下子更新差距太大,网上呢又没有合适的资源和文章,导致步履维艰。

有人肯定会问,既然升级为什么不直接一步到位呢?你可以猜猜哦😏

相关推荐
小李飞飞砖11 分钟前
Android 依赖注入框架详解
android
SUNxuetian13 分钟前
【Android Studio】升级AGP-8.6.1,Find Usage对Method失效的处理方法!
android·ide·gradle·android studio·安卓
阿华的代码王国26 分钟前
【Android】搭配安卓环境及设备连接
android·java
__water1 小时前
RHA《Unity兼容AndroidStudio打Apk包》
android·unity·jdk·游戏引擎·sdk·打包·androidstudio
绝无仅有3 小时前
企微审批对接错误与解决方案
后端·算法·架构
一起搞IT吧3 小时前
相机Camera日志实例分析之五:相机Camx【萌拍闪光灯后置拍照】单帧流程日志详解
android·图像处理·数码相机
写不出来就跑路4 小时前
Spring Security架构与实战全解析
java·spring·架构
浩浩乎@4 小时前
【openGLES】安卓端EGL的使用
android
Patrick_Wilson4 小时前
青苔漫染待客迟
前端·设计模式·架构
Kotlin上海用户组5 小时前
Koin vs. Hilt——最流行的 Android DI 框架全方位对比
android·架构·kotlin