美文网首页
Android - Gradle8.0.0+?从Gradle-D

Android - Gradle8.0.0+?从Gradle-D

作者: Cosecant | 来源:发表于2023-06-14 16:53 被阅读0次

    升级总是伴随着痛苦,总是因为一些类的变动,查无此类、此方法、此属性,让人真是头大。不经一番彻骨寒,哪有梅花扑鼻香?下面是我升级中遇到的一些问题,我在这里做个简单的记录。如果不巧你也正在因为此事犯疑惑,那请看看以下内容是否能够帮到你?

    升级中的变更说明如下:

    • settings.gradle.kts

        @file:Suppress("DEPRECATION", "UnstableApiUsage")
        pluginManagement {
            repositories {
                google()
                mavenLocal()
                mavenCentral()
                gradlePluginPortal()
                maven("https://jitpack.io")
            }
        }
        dependencyResolutionManagement {
            repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
            repositories {
                google()
                //noinspection JcenterRepositoryObsolete
                jcenter()
                mavenLocal()
                mavenCentral()
                maven("https://jitpack.io")
            }
        }
        rootProject.name = "KtsDemo"
        include(":app")
      
    • 根目录 build.gradle.kts

        import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
        buildscript {
            val objectboxVersion by extra("3.6.0") //ext { ... } 的替代内容
            dependencies {
                classpath("io.objectbox:objectbox-gradle-plugin:$objectboxVersion")
            }
        }
      
        // 增加一下配置,防止出现错误:task (current target is 1.8) and 'kaptGenerateStubsUatDebugKotlin' task (current target is 17)
        allprojects {
            tasks.withType(KotlinCompile::class.java) {
                kotlinOptions {
                    jvmTarget = "1.8"
                }
            }
        }
      
        // 新式插件引入样式,注意ksp的引入需要与kotlin版本匹配,不然会报错
        plugins {
            id("com.android.application") version "8.0.0" apply false
            id("com.android.library") version "8.0.0" apply false
            id("org.jetbrains.kotlin.android") version "1.8.20" apply false
            id("com.google.devtools.ksp") version "1.8.20-1.0.11" apply false
        }
      
        apply(from = "本地的gradle.kts") //如果是导入第三方,使用apply(plugin="plugin名称")
      
      • 附言:
        如果项目中引入了外部的 Gradle.kts 文件,那么 Gradle.kts 中声明配置可如下:
            val appRootConfig by extra(mutableMapOf(
                "namespace" to "com.kts.demo",
                "appName" to "Demo",
                "applicationId" to "com.kts.demo"
            ))
        
    • 子模块 build.gradle.kts

        // 引入Plugin
        plugins {
            id("com.android.application")
            id("org.jetbrains.kotlin.android")
            id("kotlin-kapt") //kapt可与ksp并存,因为有些第三方的还未切换到ksp
            id("kotlin-parcelize")
            id("com.google.devtools.ksp") //引入ksp
        }
      
        // 引入根目录引入的外部gradle.kts的相关配置
        val appRootConfig by extra(rootProject.extra["appRootConfig"] as Map<String, *>)
      
        android {
      
            // 签名的导入
            signingConfigs {
                // 因为dev不存在,因此使用create方法
                create("dev") {
                    keyAlias = "Test"
                    keyPassword = "123456"
                    storePassword = "123456"
                    storeFile = file("./docs/sign-test.jks") //定位jsk签名文件位置
                }
            }
      
            namespace = appRootConfig["namespace"] as String //使用全局的配置属性
            compileSdk = 33
            buildToolsVersion = "33.0.0"
      
            defaultConfig {
                applicationId = appRootConfig["applicationId"] as String
                minSdk = 21
                targetSdk = 33
                versionCode = 1
                versionName = "1.0.0"
      
                testInstrumentationRunner = "..." //此处省略
      
                // 声明BuildConfig变量,需配置buildFeatures { buildConfig = true }
                buildConfigField("String", "APP_ENV_MODE", "\"DEBUG\"")
      
                // 如果有cpp相关的编译
                externalNativeBuild {
                    cmake {
                        cppFlags("")
                        abiFilters.add("armeabi-v7a") //add或者addAll
                    }
                }
      
                // 如果配置有NDK
                ndk { abiFilters.addAll(listOf("armeabi-v7a", "x86")) }
      
                // 如果有默认签名
                signingConfig = signingConfigs.getByName("dev")
            }
      
            buildFeatures {
                viewBinding = true
                buildConfig = true // 增加该属性,项目才能生成BuildConfig类
            }
      
            sourceSets {
                // 又创建了一个渠道:google,并引入它的清单文件
                create("google") {
                    manifest.srcFile("src/google/AndroidManifest.xml")
                }
            }
      
            kotlinOptions { jvmTarget = "1.8" } //指定使用Java8编译
            compileOptions {
                encoding = "UTF-8"
                sourceCompatibility = JavaVersion.VERSION_1_8
                targetCompatibility = JavaVersion.VERSION_1_8
            }
            packaging {
                resources {
                    merges.addAll(listOf("**/LICENSE.txt", "**/NOTICE.txt"))
                    excludes.addAll(listOf("/META-INF/{AL2.0,LGPL2.1}", "DebugProbesKt.bin"))
                }
            }
            flavorDimensions.addAll(listOf("prod")) //原来写法是:flavorDimensions = ["a", "b"]
                productFlavors {
                    // 创建一个“风味”名称
                    create("google") {
                        dimension = "prod"
                        versionCode = 1
                        versionName = "1.0.0"
                        applicationId = "com.demo.kts"
                        buildConfigField("String", "APP_CHANNEL_NAME", "\"Google\"")
                    }
                }
            }
      
            buildTypes {
                // debug { signingConfig signingConfigs.dev }
                release {
                    isDebuggable = true
                    isJniDebuggable = true
                    isMinifyEnabled = true
                    isShrinkResources = true
                    signingConfig = signingConfigs.getByName("dev")
                    //noinspection ChromeOsAbiSupport
                    ndk { abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86_64")) }
                    proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
                }
            }
      
            dependencies {
                implementation("androidx.core:core-ktx:1.10.1")
                implementation("androidx.activity:activity-ktx:1.7.2")
                implementation("androidx.fragment:fragment-ktx:1.6.0")
                implementation("androidx.appcompat:appcompat:1.6.1")
                implementation("com.google.android.material:material:1.9.0")
                implementation("androidx.constraintlayout:constraintlayout:2.1.4")
                //... 省略许多,许多
                api(project(":common")) //引入其他模块
                implementation(project(":test")) //引入其他模块
            }
        }
      
      • 其他需要注意的事项
        因为项目使用的Gradle8.0.0+,所以R8模式是默认全开的,会导致一些类在经过混淆后出现问题,特别典型的是:Gson库,请看:ISSUE。通过尝试,需要设置如下规则:

        Gson混淆规则:

            ##---------------Begin: proguard configuration for Gson ----------
            # Gson uses generic type information stored in a class file when working with fields. Proguard
            # removes such information by default, so configure it to keep all of it.
            # Gson specific classes
            # -keep class sun.misc.Unsafe { *; }
            # Gson uses generic type information stored in a class file when working with
            # fields. Proguard removes such information by default, keep it.
            # -keepattributes Signature
            # This is also needed for R8 in compat mode since multiple
            # optimizations will remove the generic signature such as class
            # merging and argument removal. See:
            # https://r8.googlesource.com/r8/+/refs/heads/main/compatibility-faq.md#troubleshooting-gson-gson
            -keep class com.google.gson.reflect.TypeToken { *; }
            -keep class * extends com.google.gson.reflect.TypeToken
            # Optional. For using GSON @Expose annotation
            -keepattributes AnnotationDefault,RuntimeVisibleAnnotations
            -keepclassmembers class * {
            !transient <fields>;
            }
            -if class *
            -keepclasseswithmembers class <1> {
                <init>(...);
                @com.google.gson.annotations.SerializedName <fields>;
            }
            ##---------------End: proguard configuration for Gson ----------
        

        Retrofit也需要做如下混淆:

            -if interface * { @retrofit2.http.* public *** *(...); }
            -keep,allowoptimization,allowshrinking,allowobfuscation class <3>
        
            # Platform calls Class.forName on types which do not exist on Android to determine platform.
            -dontnote retrofit2.Platform
        

        针对协程相关的混淆:

            # -keepattributes Signature
            -keep class kotlin.coroutines.Continuation
        

        ** 如果在升级kotlin-dsl出现Parcelable报错等问题,试试读取使用方法BundleCompat.getParcelable*(args) **

    • 一步一个脚印,总算是解决了升级的问题。如果觉得有帮助,麻烦动动您发财的小手给点个赞!原创内容,转载请注明作者和出处,谢谢!

    对了,这里在增加一个WARING! 虽然上面的内容都正常运转了,我还是遇到了一个新问题,就是打包时,如何用kts给APK重命名,使其打包出来就是我们想要的名字,因为原来的 output.setOutputFileName 已经无法使用,暂未找到解决方案,正在探索中。。。

    相关文章

      网友评论

          本文标题:Android - Gradle8.0.0+?从Gradle-D

          本文链接:https://www.haomeiwen.com/subject/bickydtx.html