java.lang.RuntimeException:调用公共android.arch.lifecycle.LiveData()失败,无参数
我试图使用改型和Android架构组件调用API,但我遇到了这个错误 java.lang.RuntimeException:调用公共android.arch.lifecycle.LiveData()失败,无参数 这是响应的数据类java.lang.RuntimeException:调用公共android.arch.lifecycle.LiveData()失败,无参数,android,kotlin,gson,retrofit,android-architecture-components,Android,Kotlin,Gson,Retrofit,Android Architecture Components,我试图使用改型和Android架构组件调用API,但我遇到了这个错误 java.lang.RuntimeException:调用公共android.arch.lifecycle.LiveData()失败,无参数 这是响应的数据类 data class ForecastResult(val city: City, val list: List<Forecast>) 数据类预测结果(val城市:城市,val列表:列表) 服务接口 interface ServicesApis { //
data class ForecastResult(val city: City, val list: List<Forecast>)
数据类预测结果(val城市:城市,val列表:列表)
服务接口
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>>
}
接口服务使用虚拟数据
@获取(“数据/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”):调用
}
以及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
}
}
class-WeatherRepoImpl:WeatherRepo{
覆盖getDailyForecast():LiveData{
val预测:MutableLiveData=MutableLiveData()
RestAPI.getAPIsrevice().getForecast().enqueue(对象:回调{
覆盖fun onResponse(调用:调用?,响应:响应?){
什么时候{
响应!!.isSuccessful->{
forecast.postValue(Resource.success(response.body()?.value))
}
其他->{
val exception=AppException(responseBody=response.errorBody())
forecast.postValue(Resource.error(异常))
}
}
}
覆盖失效时的乐趣(调用:调用?、t:可丢弃?){
val exception=AppException(t)
forecast.postValue(Resource.error(异常))
}
})
回报预测
}
}
谢谢你的帮助 是,因此您的API响应可能没有正确序列化 无论如何,将
LiveData
包装为API响应是没有意义的。让你的暴露对象像这样:
someLivedataObject: LiveData<YourApiResponseModel>
// So whenever the APIs response comes in:
someLivedataObject.postValue(YourApiResponseModel)
您可以在文档中阅读更多关于它们之间差异的信息,注意我正在调用LiveData#setValue()
方法,不要使用Kotlin的尊重设置器方法
而且,由于您的视图正在观察对已公开的someLivedataObject
的更改,因此UI将更新
这与RxJava类似,在RxJava中,带有可观察包装器的API响应实际上没有意义,它不是一个连续的数据流,因此使用
单个更有意义
对这些建议持保留态度,我并不完全了解应用程序的用例,而且这些规则也有例外,我使用LiveDataAdapter
将Call
转换为LiveData
,这样你就不需要将改型响应包装为Call
。
该适配器类似于Jake的Rx适配器
从中获取LiveDataAdapterFactory
和LiveDataAdapter
添加适配器后,您需要设置它:
Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.baseUrl(BASE_URL)
.client(httpClient)
.build()
自我提升:我在以下位置制作了一个视频:从API调用中删除LiveData并创建ViewModel
类包含在MutableLiveData
对象中
例如:
API调用定义如下:(删除LiveData)
因此,您可以在ViewModel类中使用livedata。也许这不是问题所在,您可以向我们展示改型API界面吗?我已经更新了post调用
您有合适的转换器吗?您使用过存储库吗?您还有数据库吗?有你的项目的样本给我看吗?谢谢,问题出在资源类中,该类创建用于包装响应和例外谢谢你,马哈茂德·穆斯塔法,我有同样的问题,原因也在同一个地方!;)@马哈茂德·穆斯塔法(mahmoud moustafa)太棒了。这可以帮你解决问题,别忘了根据SO指南投票并接受答案。:)
Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.baseUrl(BASE_URL)
.client(httpClient)
.build()
@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>
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
}
})
}
}
yourViewModelClassObj?.allObjLiveData?.observe(this, Observer {
//whenever object change this method call every time.
}
})