admin管理员组文章数量:1122846
Question
Why does the error java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
occur in the release build when making a request using Retrofit
?
Context
I am using the following libraries:
androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7
com.squareup.retrofit2:retrofit:2.9.0
com.squareup.retrofit2:converter-gson:2.9.0
com.google.code.gson:gson:2.10.1
Here is the model code:
package com.byteflipper.ffsensitivities.data
import kotlinx.serialization.Serializable
@Serializable
data class Manufacturer(
val showInProductionApp: Boolean,
val isAvailable: Boolean,
val name: String,
val model: String
)
@Serializable
data class ManufacturerResponse(
val manufacturers: List<Manufacturer>
)
- I am using
Retrofit
to fetch data:
package com.byteflipper.ffsensitivities.service
import com.byteflipper.ffsensitivities.data.ManufacturerResponse
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
interface ApiService {
@GET("sensitivity_settings/manufacturers.json")
suspend fun getManufacturers(): ManufacturerResponse
}
object RetrofitInstance {
private const val BASE_URL = "/"
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
- ViewModel
package com.byteflipper.ffsensitivities.viewmodel
import androidxpose.runtime.State
import androidxpose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.byteflipper.ffsensitivities.data.Manufacturer
import com.byteflipper.ffsensitivities.service.RetrofitInstance
import com.byteflipper.ffsensitivities.ui.UiState
import kotlinx.coroutines.launch
import java.UnknownHostException
class ManufacturerViewModel : ViewModel() {
private val _uiState = mutableStateOf<UiState<List<Manufacturer>>>(UiState.Loading)
val uiState: State<UiState<List<Manufacturer>>> = _uiState
init {
fetchManufacturers()
}
private fun fetchManufacturers() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val response = RetrofitInstance.api.getManufacturers()
_uiState.value = UiState.Success(response.manufacturers)
} catch (e: UnknownHostException) {
_uiState.value = UiState.NoInternet
} catch (e: Exception) {
_uiState.value = UiState.Error("Ошибка загрузки данных: ${e.message}")
}
}
}
fun retry() {
fetchManufacturers()
}
}
- Release build config
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
debug {
applicationIdSuffix = ".debug"
}
}
- Everything works fine in the debug build, but the error occurs in the release build.
- Minify and Proguard are enabled (Gradle 8.10.2)
All source code here:
I tried to fix the error by changing Proguard rules to preserve the type information in Manufacturer
and ManufacturerResponse
:
# Gson requires keeping data classes and fields for serialization/deserialization.
-keep class com.byteflipper.ffsensitivities.data.** { *; }
-keepclassmembers class com.byteflipper.ffsensitivities.data.** {
<fields>;
}
# Keep generic type information for Retrofit/Gson.
-keepattributes Signature
-keepclassmembers class * {
@retrofit2.http.* <methods>;
}
Question
Why does the error java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
occur in the release build when making a request using Retrofit
?
Context
I am using the following libraries:
androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7
com.squareup.retrofit2:retrofit:2.9.0
com.squareup.retrofit2:converter-gson:2.9.0
com.google.code.gson:gson:2.10.1
Here is the model code:
package com.byteflipper.ffsensitivities.data
import kotlinx.serialization.Serializable
@Serializable
data class Manufacturer(
val showInProductionApp: Boolean,
val isAvailable: Boolean,
val name: String,
val model: String
)
@Serializable
data class ManufacturerResponse(
val manufacturers: List<Manufacturer>
)
- I am using
Retrofit
to fetch data:
package com.byteflipper.ffsensitivities.service
import com.byteflipper.ffsensitivities.data.ManufacturerResponse
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
interface ApiService {
@GET("sensitivity_settings/manufacturers.json")
suspend fun getManufacturers(): ManufacturerResponse
}
object RetrofitInstance {
private const val BASE_URL = "https://raw.githubusercontent.com/ByteFlipper-58/FFSensitivities/refs/heads/master/app/src/main/assets/"
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
- ViewModel
package com.byteflipper.ffsensitivities.viewmodel
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.byteflipper.ffsensitivities.data.Manufacturer
import com.byteflipper.ffsensitivities.service.RetrofitInstance
import com.byteflipper.ffsensitivities.ui.UiState
import kotlinx.coroutines.launch
import java.net.UnknownHostException
class ManufacturerViewModel : ViewModel() {
private val _uiState = mutableStateOf<UiState<List<Manufacturer>>>(UiState.Loading)
val uiState: State<UiState<List<Manufacturer>>> = _uiState
init {
fetchManufacturers()
}
private fun fetchManufacturers() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val response = RetrofitInstance.api.getManufacturers()
_uiState.value = UiState.Success(response.manufacturers)
} catch (e: UnknownHostException) {
_uiState.value = UiState.NoInternet
} catch (e: Exception) {
_uiState.value = UiState.Error("Ошибка загрузки данных: ${e.message}")
}
}
}
fun retry() {
fetchManufacturers()
}
}
- Release build config
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
debug {
applicationIdSuffix = ".debug"
}
}
- Everything works fine in the debug build, but the error occurs in the release build.
- Minify and Proguard are enabled (Gradle 8.10.2)
All source code here: https://github.com/ByteFlipper-58/FFSensitivities2/tree/master/app/src/main/java/com/byteflipper/ffsensitivities
I tried to fix the error by changing Proguard rules to preserve the type information in Manufacturer
and ManufacturerResponse
:
# Gson requires keeping data classes and fields for serialization/deserialization.
-keep class com.byteflipper.ffsensitivities.data.** { *; }
-keepclassmembers class com.byteflipper.ffsensitivities.data.** {
<fields>;
}
# Keep generic type information for Retrofit/Gson.
-keepattributes Signature
-keepclassmembers class * {
@retrofit2.http.* <methods>;
}
Share
Improve this question
asked Nov 23, 2024 at 13:38
IbremMiner837IbremMiner837
12 bronze badges
2 Answers
Reset to default 0you need to use moshi library for this case,
You can read all document for Moshi: https://github.com/square/moshi
Can you try this code
1: impl
implementation("com.squareup.moshi:moshi-kotlin:1.15.0")
2:
android.enableR8.fullMode=true
3:
object RetrofitInstance {
private const val BASE_URL = "https://raw.githubusercontent.com/ByteFlipper-58/FFSensitivities/refs/heads/master/app/src/main/assets/"
private val moshi: Moshi by lazy {
Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
}
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
.create(ApiService::class.java)
}
}
4:
data class Manufacturer(
@Json(name = "showInProductionApp") val showInProductionApp: Boolean,
@Json(name = "isAvailable") val isAvailable: Boolean,
@Json(name = "name") val name: String,
@Json(name = "model") val model: String
)
5:
# Keep metadata for serialization
-keepattributes *Annotation*
-keep class kotlinx.serialization.** { *; }
-keepclassmembers class **$Companion { *; }
-keepclasseswithmembers class * {
@kotlinx.serialization.Serializable <fields>;
}
-keep @kotlinx.serialization.Serializable class *
# Keep your data models
-keep class com.byteflipper.ffsensitivities.data.** { *; }
6: in build.gradle
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
The same error, but I managed to get slightly more detailed logs:
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:46)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy3.getManufacturers(Unknown Source)
at com.byteflipper.ffsensitivities.viewmodel.ManufacturerViewModel$fetchManufacturers$1.invokeSuspend(ManufacturerViewModel.kt:26)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:256)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at com.byteflipper.ffsensitivities.viewmodel.ManufacturerViewModel.fetchManufacturers(ManufacturerViewModel.kt:23)
at com.byteflipper.ffsensitivities.viewmodel.ManufacturerViewModel.<init>(ManufacturerViewModel.kt:19)
package com.byteflipper.ffsensitivities.viewmodel
import android.util.Log
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.byteflipper.ffsensitivities.data.Manufacturer
import com.byteflipper.ffsensitivities.service.RetrofitInstance
import com.byteflipper.ffsensitivities.ui.UiState
import kotlinx.coroutines.launch
import java.net.UnknownHostException
class ManufacturerViewModel : ViewModel() {
private val _uiState = mutableStateOf<UiState<List<Manufacturer>>>(UiState.Loading)
val uiState: State<UiState<List<Manufacturer>>> = _uiState
init {
fetchManufacturers()
}
private fun fetchManufacturers() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val response = RetrofitInstance.api.getManufacturers()
_uiState.value = UiState.Success(response.manufacturers)
} catch (e: UnknownHostException) {
_uiState.value = UiState.NoInternet
} catch (e: Exception) {
Log.e("RetrofitError", "Ошибка загрузки данных", e)
_uiState.value = UiState.Error("Ошибка загрузки данных: ${e.localizedMessage}")
}
}
}
fun retry() {
fetchManufacturers()
}
}
本文标签: kotlinError javalangClass cannot be cast to javalangreflectParameterizedTypeStack Overflow
版权声明:本文标题:kotlin - Error java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736299371a1930438.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论