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

如何在Kotlin中使用await等待Retrofit网络请求?

实现Retrofit请求的await()调用方式

完全可以实现你想要的调用形式,但需要注意**await()是Kotlin协程的挂起方法,不能直接在主线程的非挂起函数(比如onCreate)中调用**,必须在协程作用域内执行。下面是具体实现步骤和代码示例:

1. 添加必要依赖

在项目的build.gradle(Module级别)中添加Retrofit、协程相关依赖:

// Retrofit核心
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// Gson解析器
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// Retrofit协程适配(用于支持Deferred返回类型)
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
// Android协程核心
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
// Lifecycle协程作用域(用于Activity/Fragment安全启动协程)
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'

2. 定义Retrofit接口

有两种写法适配协程调用:

// 数据实体类
data class User(val id: Int, val name: String)

interface UserApi {
    // 写法1:返回Deferred,支持调用await()获取结果
    @GET("users")
    fun getUsersDeferred(): Deferred<List<User>>

    // 写法2:直接用suspend函数(Retrofit 2.6+推荐写法,更简洁)
    @GET("users")
    suspend fun getUsers(): List<User>
}

3. 封装Repository层

class UserRepository(private val userApi: UserApi) {
    // 对应写法1,返回Deferred对象
    fun getUsersDeferred(): Deferred<List<User>> {
        return userApi.getUsersDeferred()
    }

    // 对应写法2,挂起函数
    suspend fun getUsers(): List<User> {
        return userApi.getUsers()
    }
}

4. 在Activity中调用

必须在协程作用域内执行挂起方法,这里用官方推荐的lifecycleScope(自动跟随Activity生命周期取消协程):

class MainActivity : AppCompatActivity() {
    private lateinit var userRepository: UserRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 初始化Retrofit实例
        val retrofit = Retrofit.Builder()
            .baseUrl("https://你的API基础地址/")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(CoroutineCallAdapterFactory()) // 写法1需要添加此适配器
            .build()

        // 初始化API和Repository
        val userApi = retrofit.create(UserApi::class.java)
        userRepository = UserRepository(userApi)

        // 启动协程执行请求
        lifecycleScope.launch {
            try {
                // 写法1:调用await()获取结果
                val dataFromDeferred = userRepository.getUsersDeferred().await()
                // 写法2:直接调用挂起函数
                val dataFromSuspend = userRepository.getUsers()
                
                // 处理获取到的数据
                println("用户数据:$dataFromSuspend")
            } catch (e: Exception) {
                // 处理请求异常(比如网络错误、解析错误)
                e.printStackTrace()
            }
        }
    }
}

关键注意点

  • 不能直接在onCreate这类非挂起函数中调用await()或挂起函数,会触发编译错误,必须包裹在协程作用域(如lifecycleScope.launch,不推荐使用GlobalScope.launch避免内存泄漏)内。
  • Retrofit 2.6及以上版本支持直接用suspend函数定义接口方法,无需额外的CallAdapter,写法更简洁,推荐使用这种方式。
  • 使用lifecycleScope可以避免页面销毁后协程仍在执行导致的内存泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:50:28