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

Android中使用Retrofit发起请求后如何等待服务器响应?

问题分析与解决方案

你的代码存在几个关键问题,导致无法正确等待服务器响应:

  1. Retrofit挂起函数用法错误
    你在suspend fun post()中返回了Call<gett>,这不符合Retrofit的挂起函数规范。Retrofit的挂起函数应该直接返回目标数据类型(无需Call包装),框架会自动处理挂起逻辑。

  2. 请求方法与实际接口不匹配
    你声明了@GET("/posts/add"),但dummyjson.com的/posts/add是POST接口,需要用@POST注解,否则会请求失败。

  3. 协程内错误调用execute()
    在viewModelScope的协程中,调用挂起函数时不需要手动调用execute(),直接调用即可自动挂起等待响应,execute()是同步阻塞方法,不适合在协程中使用。

  4. 异常捕获过于隐蔽
    空的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:47:23