如何将Retrofit响应体移出函数,赋值给外部变量或返回?
Retrofit 响应体赋值外部变量/返回 + WeatherData 类常见问题解决
一、Retrofit 异步数据怎么拿到外部变量或返回
Retrofit的网络请求默认是异步的——主线程不会等请求完成就继续执行,所以直接在getMyData里return响应体、或者直接给外部变量赋值都会拿到空值。给你两种实用的解决方式:
1. 用高阶函数替代固定的processData
把数据回调逻辑做成可传入的参数,这样你在调用时就能灵活处理数据(包括赋值给外部变量):
// 先定义Retrofit接口 interface ApiService { @GET("weather") fun getMyData(): Call<WeatherData> } // 封装请求函数,传入成功/失败的回调 fun fetchWeatherData( onSuccess: (WeatherData) -> Unit, onFailure: (Throwable) -> Unit ) { val retrofit = Retrofit.Builder() .baseUrl("你的接口BaseUrl") .addConverterFactory(GsonConverterFactory.create()) .build() val service = retrofit.create(ApiService::class.java) service.getMyData().enqueue(object : Callback<WeatherData> { override fun onResponse(call: Call<WeatherData>, response: Response<WeatherData>) { response.body()?.let(onSuccess) ?: onFailure(Exception("响应体为空")) } override fun onFailure(call: Call<WeatherData>, t: Throwable) { onFailure(t) } }) } // 调用时直接处理数据,赋值给外部变量 var externalWeatherData: WeatherData? = null fetchWeatherData( onSuccess = { data -> externalWeatherData = data // 这里还能做UI更新等操作 }, onFailure = { error -> // 处理请求失败逻辑,比如弹Toast } )
2. 用Kotlin协程(更简洁,推荐新手学)
先在gradle里加协程适配依赖:
implementation 'com.squareup.retrofit2:adapter-kotlin-coroutines-coroutines:2.9.0'
然后把接口改成suspend函数(协程专用):
interface ApiService { @GET("weather") suspend fun getMyData(): Response<WeatherData> }
之后在协程作用域里调用,就能像同步代码一样直接赋值/返回:
// 在ViewModel、Activity的协程作用域里调用(比如用MainScope) fun fetchWeatherData() = MainScope().launch { val retrofit = Retrofit.Builder() .baseUrl("你的接口BaseUrl") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(CoroutineCallAdapterFactory()) .build() val service = retrofit.create(ApiService::class.java) try { val response = service.getMyData() if (response.isSuccessful) { // 直接赋值给外部变量 val externalWeatherData = response.body() // 如果是suspend函数,还能直接return response.body() } } catch (e: Exception) { // 处理异常 } }
二、WeatherData类常见报错解决
你创建WeatherData时的报错,大概率是这几个新手常见问题:
1. JSON字段名和类属性名不匹配
比如接口返回的JSON是{"city":"北京","temp":25},但你类里写的是cityName、temperature,这时候要用@SerializedName注解映射:
import com.google.gson.annotations.SerializedName data class WeatherData( @SerializedName("city") val cityName: String, @SerializedName("temp") val temperature: Int )
2. 缺少无参构造函数
Gson解析需要无参构造函数,Kotlin的data类如果所有属性都有默认值会自动生成;如果没有默认值,要加@NoArg注解:
先在gradle里配置插件:
plugins { id 'kotlin-kapt' } dependencies { kapt 'com.google.gson:gson:2.10.1' }
然后给数据类加注解:
import com.google.gson.annotations.SerializedName import kotlin.jvm.JvmOverloads @NoArg data class WeatherData( val city: String, val temp: Int )
3. 数据类型不匹配
比如JSON里的temp是字符串"25",但你类里写的是Int,或者反过来,这种要对照接口返回的JSON结构,调整类属性的类型。
内容的提问来源于stack exchange,提问作者Tetsuo Rulin
相关产品推荐
相关产品推荐

