Поле сущности встроенной комнаты в объекте ответа на модернизацию, не инициализированное во время выполнения - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть объект CurrentWeatherResponse, который содержит данные JSON, восстановленные из API погоды с помощью Retrofit. Вот формат ответа JSON:

{
"latitude": 37.8267,
"longitude": -122.4233,
"timezone": "America/Los_Angeles",
"currently": {
  "time": 1587054875,
  "summary": "Mostly Cloudy",
  "icon": "partly-cloudy-day",
  "nearestStormDistance": 107,
  "nearestStormBearing": 119,
  "precipIntensity": 0,
  "precipProbability": 0,
  "temperature": 11.49,
  "apparentTemperature": 11.49,
  "dewPoint": 10.14,
  "humidity": 0.91,
  "pressure": 1012.9,
  "windSpeed": 2.73,
  "windGust": 3.84,
  "windBearing": 171,
  "cloudCover": 0.64,
  "uvIndex": 2,
  "visibility": 16.093,
  "ozone": 360.9
  },
"offset": -7
}

Внутри CurrentWeatherResponse у меня есть два поля currentWeatherEntry: CurrentWeatherEntry и val location: WeatherLocation соответственно. Каждое из этих полей представляет собой класс @Entity. Теперь я заметил, что хотя данные "currently" json успешно передаются в поле CurrentWeatherEntry, поле @Embedded location WeatherLocation никогда не инициализируется. Когда я запускаю приложение или использую инспектор базы данных, я вижу, что у сущности WeatherLocation даже поле идентификатора не инициализировано. Что мне здесь не хватает?

Класс CurrentWeatherResponse:

data class CurrentWeatherResponse(
    // Tells GSON that the "currently" field of the JSON returned by the
    // API should be tied with our CurrentWeatherEntry data class
    @SerializedName("currently")
    val currentWeatherEntry: CurrentWeatherEntry,
    @Embedded
    val location: WeatherLocation
) {
    init {
        location.setEpochTimeVal(currentWeatherEntry.time)
    }
}

Объект CurrentWeatherEntry:

const val CURRENT_WEATHER_ID = 0

@Entity(tableName = "current_weather")
data class CurrentWeatherEntry(
    val time: Long, // epoch timestamp
    val icon: String,
    val summary: String,
    val precipProbability: Double,
    val temperature: Double
) {
    @PrimaryKey(autoGenerate = false)
    var id:Int = CURRENT_WEATHER_ID
}

Объект WeatherLocaiton:

const val WEATHER_LOCATION_ID = 0

@Entity(tableName = "weather_location")
data class WeatherLocation(
    val latitude: Double,
    val longitude: Double,
    val timezone: String
) {
    @PrimaryKey(autoGenerate = false)
    var id:Int = WEATHER_LOCATION_ID

    private var epochTimeVal:Long = 0

    val zonedDateTime:ZonedDateTime
        get() {
            val instant = Instant.ofEpochMilli(this.epochTimeVal)
            val zoneId = ZoneId.of(timezone)
            return ZonedDateTime.ofInstant(instant,zoneId)
        }

    fun setEpochTimeVal(time:Long) {
        this.epochTimeVal = time}
    fun getEpochTimeVal() : Long = epochTimeVal
}

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Как и @MahdiRajabi, аннотация @Embedded используется Room, а не Gson. Это означает, что поля latitude, longitude & timezone, которые были возвращены из ответа JSON в класс CurrentWeatherResponse, были просто проигнорированы, а поле location:WeatherLocation было просто присвоено null. Я решил свою проблему, явно определив поля latitude, longitude & timezone в CurrentWeatherResponse и затем возвращая экземпляр WeatherLocation, когда к полю location обращаются с помощью метода получения. Теперь все работает как положено!

data class CurrentWeatherResponse(
    // Tells GSON that the "currently" field of the JSON returned by the
    // API should be tied with our CurrentWeatherEntry data class
    @SerializedName("currently")
    val currentWeatherEntry: CurrentWeatherEntry,
    val latitude:Double,
    val longitude:Double,
    val timezone:String
) {
    val location:WeatherLocation
        get() = WeatherLocation(latitude,longitude,timezone,currentWeatherEntry.time)
}
0 голосов
/ 17 апреля 2020

Если я правильно понял вашу проблему, я должен сказать, что аннотация @Embedded - это аннотация Room, а не аннотация Gson. Таким образом, не будет воспроизводиться правило для преобразования вашего ответа в Kotlin объект данных Retrofit.

@Embedded аннотация видна только для класса Room Dao для преобразования реляционной базы данных в вашу удобную объектную модель.

Так что вам нужно написать свой собственный TypeConvertor для Gson.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...