在Kotlin成为android的第一语言之后,我投入了自己的心血。在过去的几天中,我取得了一些进展,将现有的知识迁移到Kotlin。最近,我正在学习如何在虚拟项目中使用GSON,Retrofit和kotlin。
CurrentWeather
是在视图中显示数据的模型
data class CurrentWeather(
val latitude: Double,
val longitude: Double,
val placeName: String,
val temperature: Float,
val maxTemperature: Float,
val minTemperature: Float,
val windSpeed: Float,
val windDirection: Float,
val weatherType: String,
val weatherDescription: String,
val icon: String,
val timestamp: Instant)
类Current
负责将JSON解析为POJO类,就像我过去所做的一样,但是今天使用kotlin看起来有些不同
data class Current(@SerializedName("coord") val location: Location,
@SerializedName("weather") val weather: List<Weather>,
@SerializedName("main") val temperatureAndPressure: TemperatureAndPressure,
@SerializedName("wind") val wind: Wind,
@SerializedName("dt") val timeStamp: Long,
@SerializedName("name") val placeName: String) {
val time: Instant by fastLazy { Instant.ofEpochSecond(timeStamp) }
val currentWeather = CurrentWeather(location.latitude,
location.longitude,
placeName,
temperatureAndPressure.temperature,
temperatureAndPressure.maxTemperature,
temperatureAndPressure.minTemperature,
wind.windSpeed ?: 0f,
wind.windAngle ?: 0f,
weather[0].main,
weather[0].description,
weather[0].icon,
time)
}
即使我从改造中获得了成功的响应(我也检查了成员变量;例如位置:位置,天气:列表,temperatureAndPressure:TemperatureAndPressure等。但是,我得到了这个错误。
2018-11-12 21:04:07.455 9948-9948 / bus.green.fivedayweather E / AndroidRuntime:FATAL EXCEPTION:main 流程:bus.green.fivedayweather,PID:9948 java.lang.IllegalArgumentException:指定为非null的参数为null:方法kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull,参数p1 在bus.green.fivedayweather.ui.CurrentWeatherFragment $ retrieveForecast $ 1.invoke(未知来源:6) 在bus.green.fivedayweather.ui.CurrentWeatherFragment $ retrieveForecast $ 1.invoke(CurrentWeatherFragment.kt:20) 在bus.green.fivedayweather.net.OpenWeatherMapProvider $ RetrofitCallbackWrapper.onResponse(OpenWeatherMapProvider.kt:62)
我在解析时做错什么了吗?
答案 0 :(得分:4)
这是您的问题Parameter specified as non-null is null
。您所有的数据类都用non-null parameter constructor
声明。但是,在解析JSON过程中,有一个null参数->导致崩溃。要解决此问题,应将构造函数参数声明为可为空,如下所示:
data class Current(@SerializedName("coord") val location: Location?,
@SerializedName("weather") val weather: List<Weather>?,
@SerializedName("main") val temperatureAndPressure: TemperatureAndPressure?,
@SerializedName("wind") val wind: Wind?,
@SerializedName("dt") val timeStamp: Long?,
@SerializedName("name") val placeName: String?) {
// your CurrentWeather class should be the same.
// Of course, if you are sure with non-null parameters, you should make them non-null.
答案 1 :(得分:0)
我相信,如果通过使变量为可空类型来遵循上述解决方案,将无法解决您的问题。 在您的情况下,问题在于这种情况下Gson本身的JSON解析。首先,Gson没有对Kotlin数据类的本机支持。我建议您通读本文GSON+KOTLIN。 这篇文章的简短摘要是
val currentWeather
是数据类的实例,而使用反射的Gson无法从反序列化的JSON实例化它,因此即使您解析{{1}的成员变量,该变量也将为null。 }。我的建议是切换到Moshi,它内置了对Kotlin的支持。相反,如果您是Gson的忠实拥护者,则需要在默认值的帮助下遵循此变通办法并使变量为空类型。为此,我们基本上将构造函数参数设为私有支持属性。然后,我们为每个支持字段提供一个具有真实名称的只读属性,并将自定义get()=与Elvis运算符结合使用以定义我们的默认值或行为,从而得出不可为空的返回值。
data class Current
在我看来,在科特林统治时代的今天,格森一直无法跟上步伐。如果您只是出于学习目的而执行此项目,则绝对应该使用Moshi。它具有data class Current(@SerializedName("coord") val _location: Location?,
@SerializedName("weather") val _weather: List<Weather>?,
@SerializedName("main") val _temperatureAndPressure: TemperatureAndPressure?,
@SerializedName("wind") val _wind: Wind?,
@SerializedName("dt") val _timeStamp: Long?, = 0.0
@SerializedName("name") val _placeName: String? = "") {
val location
get() = _location ?: throw IllegalArgumentException("Location is required")
val weather
get() = _weather ?: throw IllegalArgumentException("Title is required")
val wind
get() = _wind ?: throw IllegalArgumentException("Title is required")
val temperatureAndPressure
get() = _temperatureAndPressure ?: throw IllegalArgumentException("Title is required")
......and so on
val time: Instant by fastLazy { Instant.ofEpochSecond(timeStamp) }
val currentWeather = CurrentWeather(location.latitude,
location.longitude,
placeName,
temperatureAndPressure.temperature,
temperatureAndPressure.maxTemperature,
temperatureAndPressure.minTemperature,
wind.windSpeed ?: 0f,
wind.windAngle ?: 0f,
weather[0].main,
weather[0].description,
weather[0].icon,
time)
}
,它具有对JSON的现成支持