我正在尝试使用Retrofit和Android架构组件调用API,但我收到此错误
java.lang.RuntimeException:无法调用没有args的公共android.arch.lifecycle.LiveData()
这是响应的数据类
data class ForecastResult(val city: City, val list: List<Forecast>)
服务接口
interface ServicesApis { // using dummy data
@GET("data/2.5/forecast/")
fun getForecast(@Query("APPID") APPID: String = "xxxxxxxx"
, @Query("q") q: String = "94043", @Query("mode") mode: String = "json", @Query("units") units: String = "metric"
, @Query("cnt") cnt: String = "7"): Call<LiveData<ForecastResult>>
}
和api实现
class WeatherRepoImpl : WeatherRepo {
override fun getDailyForecast(): LiveData<Resource<ForecastResult>> {
val forecast: MutableLiveData<Resource<ForecastResult>> = MutableLiveData()
RestAPI.getAPIsrevice().getForecast().enqueue(object : Callback<LiveData<ForecastResult>> {
override fun onResponse(call: Call<LiveData<ForecastResult>>?, response: Response<LiveData<ForecastResult>>?) {
when {
response!!.isSuccessful -> {
forecast.postValue(Resource.success(response.body()?.value))
}
else -> {
val exception = AppException(responseBody = response.errorBody())
forecast.postValue(Resource.error(exception))
}
}
}
override fun onFailure(call: Call<LiveData<ForecastResult>>?, t: Throwable?) {
val exception = AppException(t)
forecast.postValue(Resource.error(exception))
}
})
return forecast
}
}
感谢您的帮助!
答案 0 :(得分:1)
从API调用中删除LiveData并创建ViewModel
对象中包含的MutableLiveData
类。
例如:
API调用定义如下: (删除LiveData)
@GET("data/2.5/forecast/")
fun getForecast(@Query("APPID") APPID: String = "xxxxxxxx"
, @Query("q") q: String = "94043", @Query("mode") mode: String = "json", @Query("units") units: String = "metric"
, @Query("cnt") cnt: String = "7"): Call<ForecastResult>
创建一个ViewModel类:
class YourViewModel: ViewModel() {
var allObjLiveData = MutableLiveData<YOUROBJECT>()
fun methodForAPICall(){
mApiService?.getForecast(.....)?.enqueue(object : Callback<YOUROBJECT>
{
override fun onFailure(call: Call<YOUROBJECT>, t: Throwable) {
allObjLiveData.value = null
}
override fun onResponse(call: Call<YOUROBJECT>, response: Response<YOUROBJECT>) {
allObjLiveData.value=response.body() //Set your Object to live Data
}
})
}
}
现在在您的活动或片段初始化ViewModel类中。 并观察实时数据。
yourViewModelClassObj?.allObjLiveData?.observe(this, Observer {
//whenever object change this method call every time.
}
})
因此您可以在ViewModel类中使用实时数据。
答案 1 :(得分:0)
是的,可能您的API响应未正确序列化。
无论如何,将LiveData
包装到API响应中是没有意义的。只需像你这样暴露对象:
someLivedataObject: LiveData<YourApiResponseModel>
// So whenever the APIs response comes in:
someLivedataObject.postValue(YourApiResponseModel)
如果由于某种原因无法使用
someLivedataObject.setValue(YourApiResponseModel)
您可以在文档中详细了解这些内容之间的区别,请注意我正在调用LiveData#setValue()
方法,不要使用Kotlin的deference setter方法。
由于您的视图正在观察对已公开的someLivedataObject
的更改,因此UI已更新。
这类似于RxJava对应物,其中使用Observable包装器的API响应实际上没有意义,它不是连续的数据流,因此使用Single
更有意义。
这些建议含糊不清,我不是完全了解你的应用程序的用例这些规则有例外。
答案 2 :(得分:0)
我使用LiveDataAdapter
将Call
转换为LiveData
,这样您就不需要将您的Retrofit响应包装为Call<LiveData<T>>
。
此适配器类似于Jake的Rx适配器。
从here获取LiveDataAdapterFactory
和LiveDataAdapter
。
添加适配器后,您需要进行设置:
Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.baseUrl(BASE_URL)
.client(httpClient)
.build()
自我推广:我已经在https://caster.io/lessons/android-architecture-components-livedata-with-retrofit
制作了相同的视频