提问人:Chirag Thummar 提问时间:4/21/2023 最后编辑:Mark RotteveelChirag Thummar 更新时间:7/15/2023 访问量:7768
将 Gradle 从 7.4.2 升级到 Gradle 8.0.0 时发布应用程序时出现错误 - java.lang.ClassCastException
Upgrading Gradle from 7.4.2 to Gradle 8.0.0 gives error on release app - java.lang.ClassCastException
问:
我最近将 Android Studio 升级到了 Flamingo,并将 Gradle 从 7.4.2 升级到了 8.0.0。在版本 7.4.2 中一切正常。
当我使用 Gradle 8.0.0 生成签名的 APK 时,它给了我一个运行时错误。java.lang.ClassCastException
我尝试了很多解决方案,例如为 Retrofit、Okio、OkHTTP 等添加 Proguard 规则,但它仍然给我这样的错误。
注意:当我从 8.0.0 降级到 7.4.2 时,它正在工作。
所以任何人都可以帮助我发现AGP 8.0.0的问题。
build.gradle(应用程序)
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'kotlin-parcelize'
id 'com.google.dagger.hilt.android'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
}
android {
compileSdk 33
defaultConfig {
minSdk 24
targetSdk 33
versionCode 22
versionName "1.0.16"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
/*vectorDrawables {
useSupportLibrary true
}*/
def localPropertiesFile = rootProject.file("local.properties")
def localProperties = new Properties()
localProperties.load(new FileInputStream(localPropertiesFile))
buildConfigField "String", "API_KEY", localProperties['API_KEY']
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
buildFeatures {
compose true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion '1.4.2'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
bundle {
language {
enableSplit = false
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.10.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.google.accompanist:accompanist-permissions:0.24.11-rc'
implementation 'com.google.accompanist:accompanist-webview:0.24.11-rc'
implementation 'com.google.accompanist:accompanist-pager:0.24.13-rc'
implementation "com.google.accompanist:accompanist-pager-indicators:0.24.13-rc"
implementation "com.google.accompanist:accompanist-drawablepainter:0.25.1"
implementation "com.google.accompanist:accompanist-flowlayout:0.31.0-alpha"
implementation 'androidx.activity:activity-compose:1.7.1'
implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.material:material'
// implementation 'androidx.compose.material3:material3'
implementation "androidx.navigation:navigation-compose:2.5.3"
implementation 'com.google.firebase:protolite-well-known-types:18.0.0'
implementation "androidx.compose.ui:ui-viewbinding"
implementation project(path: ':pdfviewer')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
implementation "com.google.dagger:hilt-android:2.45"
debugImplementation "androidx.compose.ui:ui-test-manifest"
kapt "com.google.dagger:hilt-compiler:2.45"
kapt "androidx.hilt:hilt-compiler:1.0.0"
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'
implementation "androidx.activity:activity-ktx:1.7.1"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation "androidx.lifecycle:lifecycle-process:2.6.1"
kapt "androidx.lifecycle:lifecycle-compiler:2.6.1"
/* *****************************************************
**** Retrofit2
****************************************************** */
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation "com.squareup.okhttp3:okhttp:4.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.9.0"
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation "androidx.room:room-runtime:2.5.1"
kapt "androidx.room:room-compiler:2.5.1"
implementation "androidx.room:room-ktx:2.5.1"
implementation 'androidx.core:core-splashscreen:1.0.1'
def billing_version = "5.2.0"
implementation "com.android.billingclient:billing:$billing_version"
implementation "com.android.billingclient:billing-ktx:$billing_version"
implementation 'com.google.firebase:firebase-crashlytics-buildtools:2.9.5'
implementation platform('com.google.firebase:firebase-bom:31.1.0')
implementation 'com.google.firebase:firebase-config-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-messaging-ktx'
implementation 'com.google.android.gms:play-services-ads:22.0.0'
implementation 'com.airbnb.android:lottie-compose:4.0.0'
}
kapt {
correctErrorTypes true
}
Project Gradle 文件
buildscript {
ext {
compose_ui_version = '1.5.0-alpha02'
kotlin_version = '1.8.10'
}
dependencies {
// Add this line
classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
repositories {
mavenCentral()
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
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.10' apply false
id 'com.google.dagger.hilt.android' version '2.44' apply false
}
答:
很可能您正在使用与 Gradle 8.0 不兼容的插件。如果没有必要升级到 Gradle 8.0,我建议您降级回 7.4.2,直到这些插件变得兼容。另一种方法是检查不兼容的插件,并在可以添加时尝试替换它们。
评论
由于 Parcelize 插件,我遇到了这个问题。我正在使用 Parcelize 插件在活动之间传递自定义对象 ArrayList。
经过多次尝试,终于找到了更改 proguard-rules.pro 文件的解决方案。
这是我 proguard-rules.pro 文件的内容
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontwarn rx.**
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>;
}
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt and other security providers are available.
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
-repackageclasses
-ignorewarnings
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
# Keep inherited services.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
#-keep public class com.itextpdf.**
-keep class com.itextpdf.** { *; }
-dontwarn com.itextpdf.*
-renamesourcefileattribute SourceFile
-dontwarn retrofit2.**
-keep class retrofit2.** {*;}
##---------------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.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep class com.google.gson.reflect.TypeToken
-keep class * extends com.google.gson.reflect.TypeToken
-keep public class * implements java.lang.reflect.Type
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
##---------------End: proguard configuration for Gson ----------
-dontwarn org.slf4j.**
-keepdirectories src/main/res/font/*
-dontusemixedcaseclassnames
-verbose
-keepattributes *Annotation*
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# Firebase
-keep class com.google.android.gms.** { *; }
-keep class com.google.firebase.** { *; }
# in order to provide the most meaningful crash reports, add the following line:
-keepattributes SourceFile,LineNumberTable
# If you are using custom exceptions, add this line so that custom exception types are skipped during obfuscation:
-keep public class * extends java.lang.Exception
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**
# Jackson
-keep @com.fasterxml.jackson.annotation.JsonIgnoreProperties class * { *; }
-keep class com.fasterxml.** { *; }
-keep class org.codehaus.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepclassmembers public final enum com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility {
public static final com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility *;
}
# General
-keepattributes SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,Signature,Exceptions,InnerClasses
此代码用于 parcelize 插件
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
评论
升级到 AGP 8.0.1 后,发布的解决方案对我不起作用。我仍然收到 Retrofit 创建并通过 Dagger 模块提供的接口的 ClassCastException。
我能够使用注释来修复它。这将告诉编译器将接口保留在生成的字节码中,即使它未在代码中的其他任何地方使用。java.lang.ClassCastException
@Keep
例如:
@Keep
interface MyApi {
...
}
评论
-keep interface company.package.** { *; }
我认为禁用 R8 全模式是解决方案,直到所有库都更新到 Gradle 8 并考虑 R8 全模式规则。
在 gradle.properties 中添加以下行:
android.enableR8.fullMode=false
评论
Execution failed for task ':app:minifyReleaseWithR8'. A failure occurred while executing com.android.build.gradle.internal.tasks.R8Task$R8Runnable
ERROR: R8: Missing class com.google.errorprone.annotations.DoNotMock (referenced from: autodispose2.ScopeProvider and 1 other context)
-dontwarn com.google.errorprone.annotations.**
app/proguard-rules.pro
评论