Android中使用Retrofit发起请求后如何等待服务器响应?
问题分析与解决方案
你的代码存在几个关键问题,导致无法正确等待服务器响应:
Retrofit挂起函数用法错误
你在suspend fun post()中返回了Call<gett>,这不符合Retrofit的挂起函数规范。Retrofit的挂起函数应该直接返回目标数据类型(无需Call包装),框架会自动处理挂起逻辑。请求方法与实际接口不匹配
你声明了@GET("/posts/add"),但dummyjson.com的/posts/add是POST接口,需要用@POST注解,否则会请求失败。协程内错误调用
execute()
在viewModelScope的协程中,调用挂起函数时不需要手动调用execute(),直接调用即可自动挂起等待响应,execute()是同步阻塞方法,不适合在协程中使用。异常捕获过于隐蔽
空的catch块会掩盖错误信息,无法排查请求失败的原因。
修正后的代码
1. 修正ApiInterface
interface ApiInterface { // 改为POST注解,挂起函数直接返回数据类 @POST("/posts/add") suspend fun post(@Body request: PostRequest): GetResponse companion object { const val BASE_URL = "https://dummyjson.com" fun create(): ApiInterface { val retrofit = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_URL) .build() return retrofit.create(ApiInterface::class.java) } } } // 添加POST请求体数据类(根据dummyjson接口要求) data class PostRequest( val title: String, val userId: Int )
2. 修正数据类(规范命名)
data class GetResponse( val title: String, val userId: Int, val id: Int // dummyjson返回的响应包含id字段,建议加上避免解析失败 )
3. 修正MainViewModel
class MainViewModel: ViewModel() { private val api = ApiInterface.create() fun fetch() { viewModelScope.launch { try { // 构造请求体,根据接口要求传入参数 val request = PostRequest("My New Post", 1) // 直接调用挂起函数,自动挂起等待响应 val response = api.post(request) Log.d("Log", "userId: ${response.userId}, title: ${response.title}") // 这里可以执行后续操作,比如保存token、更新UI等 } catch (e: Exception) { // 打印异常信息便于调试 Log.e("Log", "请求失败: ${e.message}", e) } } } }
关键说明
- 挂起函数配合
viewModelScope可以自动在后台线程执行请求,请求完成后切回主线程,无需手动处理线程切换。 - 确保权限配置:在
AndroidManifest.xml中添加网络权限<uses-permission android:name="android.permission.INTERNET" />。 - 如果需要将响应结果通知UI,可以使用
LiveData或StateFlow,比如在ViewModel中定义private val _response = MutableLiveData<GetResponse>(),然后在请求成功后_response.value = response,UI层观察这个LiveData即可。
内容的提问来源于stack exchange,提问作者Nikita
相关产品推荐
相关产品推荐

