升级AGP至8.0后Release构建Retrofit泛型类型异常求助
问题:升级AGP 8.0(Android Studio Flamingo)后Retrofit在Release构建中抛出泛型类型异常
迁移至Android Studio Flamingo并将AGP版本升级至8.0后,使用Retrofit调用API时仅在Release构建中出现如下异常,Debug构建可正常运行:
java.lang.IllegalArgumentException: Response must include generic type (e.g., Response
)
API调用代码
fun getIpApiData() = viewModelScope.launch { ipApiLiveData.postValue(Resource.Loading()) try { if (AppUtility.hasInternetConnection()) { AppUtility.showProdLog("INSIDE IP API") val response = repository.getIpApiJson(AppConstants.IP_API_FIELDS) ipApiLiveData.postValue(handleIpApiResponse(response)) AppUtility.showProdLog("IP API SUCCESS") } else { ipApiLiveData.postValue(Resource.Error(app.getString(R.string.internet_connection), AppConstants.ERROR_CODES.APP_ERROR_CODE)) } } catch (e: Exception) { AppUtility.showProdLog("EXCEPTION IP API - $e") AppUtility.showProdLog("EXCEPTION IP API - ${e.message}") val errorMsg = handleException(e) ipApiLiveData.postValue(Resource.Error(errorMsg, AppConstants.ERROR_CODES.APP_ERROR_CODE)) } } suspend fun getIpApiJson(fields: String) = RetrofitInstance.buildServiceWithURL(IGToolsAPI::class.java, IP_API_BASE_URL).getIpApiJson(fields) @GET("json") suspend fun getIpApiJson(@Query("fields") fields: String): Response<IpApiJson>
当前ProGuard配置
-keep class com.google.gson.reflect.TypeToken -keep class * extends com.google.gson.reflect.TypeToken -keep public class * implements java.lang.reflect.Type # 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 annotation used for build tooling. -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement # 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> # 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 # R8 full mode strips generic signatures from return types if not kept. -if interface * { @retrofit2.http.* public *** *(...); } -keep,allowoptimization,allowshrinking,allowobfuscation class <3>
解决方案
该问题源于AGP 8.0默认启用的R8全模式过度剥离了泛型签名,导致Retrofit无法识别Response<IpApiJson>的泛型参数,以下是针对性修复步骤:
1. 补充Retrofit泛型签名保留规则
在ProGuard规则中添加以下配置,精准匹配返回Response<*>的Retrofit接口方法,确保泛型信息不被剥离:
# 保留Retrofit服务方法的Response泛型签名 -if interface * { @retrofit2.http.* public retrofit2.Response<*> *(...); } -keep,allowoptimization,allowshrinking,allowobfuscation class <3>
2. 显式保留数据模型类结构
确保IpApiJson模型类不被混淆,且其字段与泛型信息(如果有)完整保留,添加:
# 替换为IpApiJson实际所在包路径 -keep class com.your.package.IpApiJson { *; } # 若模型类包含泛型字段,强制保留签名 -keepattributes Signature
3. 调整R8全模式配置(临时方案)
若暂时无法适配全模式,可在gradle.properties中关闭全模式:
android.enableR8.fullMode=false
注:长期建议适配全模式,以获得更优的代码压缩效果。
4. 更新Retrofit版本(可选)
确保使用适配AGP 8.0的Retrofit稳定版本(如2.9.0及以上),旧版本对R8全模式的兼容性较差。
内容的提问来源于stack exchange,提问作者Ankush Kapoor
相关产品推荐
相关产品推荐

