AGP 8.2与Java17迁移中Retrofit+Kotlin序列化混淆问题
AGP 8.2 + Java 17迁移后Retrofit+Kotlin序列化混淆报错解决
将Android Gradle Plugin(AGP)从7.4.2升级到8.2、Java版本从11升到17后,Retrofit接口调用出现混淆错误:Unable to create @Body converter for class package.api.data.device.DevicesBody (parameter #1) for method a.a
项目使用Retrofit 2结合Kotlin Serialization(kotlinx.serialization),除API调用外其他功能正常。禁用混淆(minifyEnabled false)或添加全保留规则(-keep class ** { *; })能临时解决,但不符合代码优化要求。
相关代码
private val json = kotlinx.serialization.json.Json { prettyPrint = true ignoreUnknownKeys = true explicitNulls = false } private val contentType = "application/json".toMediaType() private val retrofit: Retrofit by lazy { Retrofit.Builder() .addConverterFactory(json.asConverterFactory(contentType)) .baseUrl(baseUrl) .client(httpClient) .build() } @Keep @Serializable data class DevicesBody( @SerialName("dh_info") val dhInfo: DhInfo ) @Keep @Serializable data class DhInfo( @SerialName("type") val type: String, @SerialName("value") val value: String ) @POST("devices") suspend fun postDevice(@Body requestBody: DevicesBody): Response<DevicesResponse>
异常信息
MESSAGE: Unable to create @Body converter for class {my_package}.api.data.device.DevicesBody (parameter #1) for method a.a STACKTRACE: [retrofit2.Utils.methodError(Utils.java:54), retrofit2.Utils.parameterError(Utils.java:60), retrofit2.RequestFactory$Builder.parseParameterAnnotation(RequestFactory.java:781), retrofit2.RequestFactory$Builder.parseParameter(RequestFactory.java:325), retrofit2.RequestFactory$Builder.build(RequestFactory.java:206), retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:67), retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:26), retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202), retrofit2.Retrofit$1.invoke(Retrofit.java:160), java.lang.reflect.Proxy.invoke(Proxy.java:1006), $Proxy5.a(Unknown Source), g0.j0.invokeSuspend(SourceFile:1), g0.j0.invoke(SourceFile:1), c.g.a(SourceFile:0), g0.k0.invokeSuspend(SourceFile:0), g0.k0.invoke(SourceFile:1), kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61), kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:230),
AGP 8.2迁移改动
1. app/build.gradle
dependencies { classpath "com.android.tools.build:gradle:8.2.0" } compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = '17' }
2. gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
3. gradle.properties
# Enable generation of the BuildConfig class android.defaults.buildfeatures.buildconfig=true # Disable on-transitive R classes android.nonTransitiveRClass=false # Disable R classes with non-final fields android.nonFinalResIds=false
4. app/proguard-rules.pro
# 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
解决方案
AGP 8.2配套的R8混淆规则更严格,即使给数据类添加了@Keep注解,Kotlin序列化所需的元信息仍可能被剥离。需在app/proguard-rules.pro中添加以下规则,保留API数据包下的所有类和枚举:
... # 保留API数据类,确保Kotlin序列化正常工作 -keep class {my_package}.api.data.** { *; } -keep public enum {my_package}.api.data.** { *; } ... # Retrofit2原有规则保留 # 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
内容的提问来源于stack exchange,提问作者romainb78
相关产品推荐
相关产品推荐

