Android Compose中Retrofit JSON转数据类失败,无法展示疾病预测结果
解决JSON转Data Class失败并在Compose中展示疾病预测结果
1. 检查Data Class定义(核心问题)
确保你的Data Class和API返回的JSON结构完全匹配,推荐用@SerializedName明确指定键名,避免命名匹配问题:
import com.google.gson.annotations.SerializedName data class DiseaseResponse( @SerializedName("disease") val disease: String )
如果API返回的disease字段可能为空,把类型设为String?并可选赋默认值,防止解析失败。
2. 确认Retrofit配置了JSON转换器
Retrofit需要转换器来处理JSON和对象的转换,确保构建Retrofit实例时添加了Gson(或Moshi)转换器:
import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory private const val BASE_URL = "你的API地址/" val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) // 必须添加这一行 .build()
如果没加转换器,Retrofit无法自动解析JSON,会直接返回原始ResponseBody,导致类型转换错误。
3. 修正API接口定义
确保接口方法的返回值是你的Data Class(如果用协程则直接返回,否则用Call<DiseaseResponse>):
import retrofit2.http.Body import retrofit2.http.POST interface DiseaseApi { @POST("predict") // 替换成你的API端点 suspend fun predictDisease(@Body symptoms: List<String>): DiseaseResponse }
4. 在ViewModel中管理状态与API调用
用ViewModel处理异步请求和状态,避免Compose重组时重复请求:
import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch import android.util.Log class DiseaseViewModel : ViewModel() { private val _predictedDisease = mutableStateOf<String?>(null) val predictedDisease = _predictedDisease private val diseaseApi = retrofit.create(DiseaseApi::class.java) fun predictSymptoms(selectedSymptoms: List<String>) { viewModelScope.launch { try { val response = diseaseApi.predictDisease(selectedSymptoms) _predictedDisease.value = response.disease } catch (e: Exception) { Log.e("DiseaseViewModel", "预测失败: ${e.message}") // 可选:设置错误提示状态 } } } }
5. 在Compose UI中展示结果
通过ViewModel的状态读取预测结果,点击按钮触发请求:
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun SymptomPredictionScreen() { val viewModel: DiseaseViewModel = viewModel() val selectedSymptoms = remember { mutableStateListOf<String>() } val predictedDisease by viewModel.predictedDisease Column(modifier = Modifier.padding(16.dp)) { // 这里添加你的症状选择UI(比如Checkbox列表,更新selectedSymptoms) Button( onClick = { viewModel.predictSymptoms(selectedSymptoms) }, modifier = Modifier.padding(top = 16.dp) ) { Text(text = "Predict") } // 展示预测结果 predictedDisease?.let { Text( text = "预测疾病:$it", modifier = Modifier.padding(top = 16.dp), fontSize = 18.sp, fontWeight = androidx.compose.ui.text.font.FontWeight.Bold ) } } }
备选方案:手动解析JSON字符串(不推荐,仅应急)
如果暂时不想用Data Class,可以直接返回ResponseBody并手动解析:
// 修改API接口 interface DiseaseApi { @POST("predict") suspend fun predictDisease(@Body symptoms: List<String>): retrofit2.ResponseBody } // 在ViewModel中解析 viewModelScope.launch { try { val responseBody = diseaseApi.predictDisease(selectedSymptoms) val jsonString = responseBody.string() val jsonObj = com.google.gson.Gson().fromJson(jsonString, com.google.gson.JsonObject::class.java) val disease = jsonObj.get("disease").asString _predictedDisease.value = disease } catch (e: Exception) { Log.e("DiseaseViewModel", "解析失败: ${e.message}") } }
内容的提问来源于stack exchange,提问作者Anirudh parida
相关产品推荐
相关产品推荐

