You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在MVVM架构下用Jetpack Compose、Retrofit及HiltViewModel实现POST请求遇阻求助

解决Jetpack Compose+MVVM+Retrofit+Hilt的POST数据提交问题

1. 核对Retrofit POST接口定义

确保POST注解、参数注解完全匹配后端接口要求:

  • JSON格式提交用@Body传递序列化数据类,禁止混用表单注解;
  • 表单提交必须添加@FormUrlEncoded注解,配合@Field或@FieldMap;
  • 检查接口路径、请求头(如Content-Type)是否和后端一致。

示例JSON请求接口:

interface ApiService {
    @POST("users")
    suspend fun createUser(@Body user: User): Response<User>
}

@Serializable
data class User(
    val name: String,
    val email: String
)

2. 检查ViewModel中的请求逻辑

通过Hilt注入Repository后,用viewModelScope处理异步请求,必须捕获异常并更新UI状态:

@HiltViewModel
class UserViewModel @Inject constructor(
    private val userRepository: UserRepository
) : ViewModel() {
    private val _uiState = MutableStateFlow<UiState>(UiState.Idle)
    val uiState: StateFlow<UiState> = _uiState

    fun submitUser(user: User) {
        viewModelScope.launch {
            _uiState.value = UiState.Loading
            try {
                val response = userRepository.createUser(user)
                _uiState.value = if (response.isSuccessful) {
                    UiState.Success(response.body())
                } else {
                    UiState.Error("提交失败:${response.message()}")
                }
            } catch (e: Exception) {
                _uiState.value = UiState.Error("网络异常:${e.message}")
            }
        }
    }

    sealed class UiState {
        object Idle : UiState()
        object Loading : UiState()
        data class Success(val user: User?) : UiState()
        data class Error(val message: String) : UiState()
    }
}

3. 确认序列化与Retrofit配置

  • 必须添加kotlinx-serialization依赖,数据类要加@Serializable注解;
  • Retrofit构建时指定JSON转换器,同时添加日志拦截器排查请求细节:
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    fun provideOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY // 打印完整请求响应
            })
            .build()
    }

    @Provides
    fun provideApiService(client: OkHttpClient): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://your-api-domain.com/")
            .client(client)
            .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
            .build()
            .create(ApiService::class.java)
    }
}

4. UI层状态收集与提交处理

在Compose中收集ViewModel状态,根据状态更新UI,同时避免重复提交:

@Composable
fun UserSubmitScreen(viewModel: UserViewModel = hiltViewModel()) {
    val uiState by viewModel.uiState.collectAsState()
    var name by remember { mutableStateOf("") }
    var email by remember { mutableStateOf("") }

    Column(
        modifier = Modifier.fillMaxSize().padding(16.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        OutlinedTextField(value = name, onValueChange = { name = it }, label = { Text("姓名") })
        OutlinedTextField(value = email, onValueChange = { email = it }, label = { Text("邮箱") })
        
        Button(
            onClick = { 
                if (name.isNotEmpty() && email.isNotEmpty()) {
                    viewModel.submitUser(User(name, email))
                }
            },
            enabled = uiState !is UserViewModel.UiState.Loading // 加载时禁用按钮
        ) {
            Text(if (uiState is UserViewModel.UiState.Loading) "提交中..." else "提交")
        }

        when (uiState) {
            is UserViewModel.UiState.Success -> Text("提交成功!", color = Color.Green)
            is UserViewModel.UiState.Error -> Text((uiState as UserViewModel.UiState.Error).message, color = Color.Red)
            else -> {}
        }
    }
}

常见排查点

  • 查看日志拦截器输出的请求体、响应码,确认参数是否正确发送;
  • 检查后端是否接收正确的Content-Type;
  • 确保AndroidManifest中添加了网络权限:<uses-permission android:name="android.permission.INTERNET"/>;
  • 排查是否存在网络代理、SSL证书问题导致请求无法到达后端。

内容的提问来源于stack exchange,提问作者Ramakrishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:13:25