Android studio 老项目升级Compose踩坑指南,Gradle7.+

795 阅读3分钟

一、首先查看官方指南

旧项目引入compose

image.png

dependencies {

    val composeBom = platform("androidx.compose:compose-bom:2023.01.00")
    implementation(composeBom)
}

看到这里想着这不是有手就行吗?「狗头」,太容易了,so按照官方文档开始吭哧吭哧的搞,配置完之后果然还是出问题了

gradle编译通过完美,运行的时候却报错:Compiler 1.4.2 不匹配

image.png

好家伙根据提示这时候就开始找版本不匹配吗?一顿翻找找到了版本对应关系发现对应的kotlinCompilerExtensionVersion compose 1.4.3版本需要kotlin 1.8.10,所以开始了我的kotlin升级之旅。最低需要kotlin版本1.5.10

image.png

image.png

二、 而kotlin升级代表先要升级gradle

android gradle插件版本 与Gradle版本以及Kotlin版本对应关系文档 Android Gradle 插件版本所需的 Gradle 版本,而gradle对应的kotlin语言版本未找到所以遇事不决可问Chatgpt(虽然经常不太靠谱)大致关系如下,仅供参考,不过从这也知道gradle必须升级到7.0以上才能获取想要的kotlin版本

image.png

三、项目gradle7.0+升级之旅

3.1、先看settings.gradle文件

image.png 将原项目中的项目的build.gradle 内容迁移到 settings.gradle 原来的build.gradle内容如下:

buildscript {
    repositories {
        mavenCentral()
        google()
        maven { url "https://jitpack.io" }
        maven { url Repository.ALI_PUBLIC }
        maven { url Repository.ALI_GOOGLE }
        maven { url Repository.ALI_GRADLE }
        maven { url Repository.WPT_GROUP }
    }
    dependencies {
        classpath Deps.CLASS_PATH_GRADLE //原gradle版本
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.KOTLIN}"
        classpath Deps.AROUTER_REGISTER
        //接入文档:https://firebase.google.com/docs/android/setup?hl=zh-cn&authuser=0
        classpath 'com.google.gms:google-services:4.3.15'
    }
}

allprojects {
    repositories {
        mavenCentral()
        google()
        maven { url "https://jitpack.io" }
        maven { url Repository.ALI_PUBLIC }
        maven { url Repository.ALI_GOOGLE }
        maven { url Repository.ALI_GRADLE }
        maven { url Repository.WPT_GROUP }
    }
}

可知将功能位置迁移,原来在工程build.gradle的buildscriptallprojects移动至setting.gradle并改名为pluginManagement 和dependencyResolutionManagement。里面的东西依旧可以按照原来的copy过来。

修改后的settings.gradle如下:

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
        maven { url "https://jitpack.io" }
        maven { url 'https://maven.aliyun.com/repository/public' } //必须为字符不可为变量,因为这个初始化最早
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" }
        maven { url 'https://maven.aliyun.com/repository/public' }
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
    }
}

rootProject.name = "HaiWai"
include ':app'

3.2、那项目的build.gralde修改

注意 buildscript 中的内容可以保留 dependencies依赖,添加classpath,不影响新的plugins方式


buildscript {
    dependencies {
        //接入文档:https://firebase.google.com/docs/android/setup?hl=zh-cn&authuser=0
        //这种方式与plugins的com.google.gms.google-services 二选一
        classpath 'com.google.gms:google-services:4.3.15'
    }
}

plugins {
    id 'com.android.application' version '7.4.1' apply false
    id 'com.android.library' version '7.4.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
    id 'com.google.gms.google-services' version '4.3.15' apply false
}


task clean(type: Delete) {
    delete rootProject.buildDir
}

3.3、app模块下的build.gradle升级

原先是:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-parcelize'


android {
....
}


修改后:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android' //这里将'kotlin-android'名称修改了一下,不改也行
    id 'kotlin-kapt'
    id 'com.google.gms.google-services'
    id 'kotlin-parcelize'
}

到这里我将项目升级为了gralde插件7.4.1,指定的gradle版本为7.5,kotlin版本为1.7.0(所以后面讲compose的版本指定为 kotlinCompilerExtensionVersion = "1.2.0") 好了可以愉快的开发了,

完整的app的build.gradle配置如下:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
    id 'com.google.gms.google-services'
    id 'kotlin-parcelize'
}


boolean developBuild = project.hasProperty("developBuild")
developBuild = Config.developBuild
println("是否开发环境:$developBuild")
List<String> taskNames = project.gradle.startParameter.taskNames
println("taskNames = ${taskNames.toListString()}") //输出 :app:assembleDebug



kapt {
    arguments {
        arg("AROUTER_MODULE_NAME", project.getName())
        arg("room.schemaLocation", "$projectDir/schemas")//room
    }
}


android {
    compileSdkVersion Versions.COMPILE_SDK
    buildToolsVersion Versions.BUILD_TOOLS

    defaultConfig {
        applicationId ""
        minSdkVersion MIN_SDK
        targetSdkVersion TARGET_SDK
        versionCode APP_CODE
        versionName APP_NAME
        ndk { abiFilters "armeabi-v7a", "arm64-v8a" }
        resConfigs "en", "en-rUS" //只保留value 跟value-en-rUS
    }

    //在构建Android App Bundles时,split块会被忽略。
    splits {
        abi {
            enable true //是否开启 abi 分包,默认不开启
            // 通过reset和include指定只打"armeabi-v7a", "arm64-v8a"类型的APK
            reset()
            include "armeabi-v7a", "arm64-v8a"
            universalApk true //是否编译一个包含全部架构的apk。
        }
    }

    //在构建Android App Bundles时的配置
    bundle {
        language {
            enableSplit = false //默认情况下App Bundle会根据不同语言生成配置APK,但这里设为false,表示 不单独打包语言配置
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    signingConfigs {
        release {
          
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true // 打包时去除无用资源 可减少1M左右
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("bool", "config_center_is_debug_mode", "false")
            manifestPlaceholders = [
                    NETWORK_SECURITY_CONFIG: "@xml/network_security_config_release"
            ]
        }

        jenkins {
            minifyEnabled true
            shrinkResources true // 打包时去除无用资源 可减少1M左右
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("bool", "config_center_is_debug_mode", "true")
            manifestPlaceholders = [
                    NETWORK_SECURITY_CONFIG: "@xml/network_security_config_debug"
            ]
        }

        debug {
            minifyEnabled false
            crunchPngs false // 关闭crunchPng优化,加快构建
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("bool", "config_center_is_debug_mode", "true")
            manifestPlaceholders = [
                    NETWORK_SECURITY_CONFIG: "@xml/network_security_config_debug"
            ]
        }
    }


    buildFeatures {
        viewBinding = true
        compose = true
    }

    composeOptions {
        kotlinCompilerExtensionVersion = "1.2.0"
    }

    packagingOptions {
        exclude 'META-INF/*'
    }

    lintOptions {
        //在 release 版本是否检查 fatal 类型错误,默认release版本为开启。开启后,检查到 fatal 类型错误则会关闭。
        setCheckReleaseBuilds(false)
        setAbortOnError(false) //是否发现错误,则停止构建。
        setIgnoreWarnings(false) //是否忽略警告,只检查error。
    }

    dexOptions {
        javaMaxHeapSize "4g"
        maxProcessCount = 8 // 最大线程数量 默认是4
        preDexLibraries true// 加快增量构建速度 第一次构建速度会慢很多
    }
}

project.afterEvaluate {
    preReleaseBuild.doFirst {
        if (developBuild) {
            throw new GradleException('release包需要打开插件开关')
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'])

    implementation Deps.AROUTER_API
    kapt Deps.AROUTER_COMPILER

     ...
 

    implementation Deps.GOOGLE_PAY_BILLING
    implementation Deps.GOOGLE_LOGIN
    implementation Deps.RETROFIT

    //使用BoM时,您不会在Firebase库依赖项中指定版本
    implementation platform('com.google.firebase:firebase-bom:30.0.1')
    //Google Analytics(分析)会收集您的应用的使用情况和行为数据。SDK 会记录两种主要类型的信息:
    implementation 'com.google.firebase:firebase-analytics-ktx'

    //https://developer.android.google.cn/jetpack/compose/bom/bom-mapping?hl=zh-cn
    def compose_version = "1.2.0"
    implementation 'androidx.activity:activity-compose:1.3.1'
    implementation 'androidx.compose.material3:material3:1.0.1'
   implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
   implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
   implementation "androidx.compose.foundation:foundation-layout:1.3.1"
    implementation "androidx.compose.foundation:foundation:1.3.1"


}

一些升级报错记录下

Build file '/Users/tanguiwu/project/andriod-qianbiapp/app/build.gradle' line: 2

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > The option 'android.enableBuildCache' is deprecated.
     The current default is 'false'.
     It was removed in version 7.0 of the Android Gradle plugin.
     The Android-specific build caches were superseded by the Gradle build cache (https://docs.gradle.org/current/userguide/build_cache.html).

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

7.1+后gradle.properties 文件中的android.enableBuildCache已经废弃

注释
android.enableBuildCache=true

image.png

参考: Android Gradle Plugin 7.4.0

Android Compose BOM 与库版本对应表

Android Compose 快速入门指南

Android Gradle 7.1+新版本依赖变化