разобранный gson возвращает ноль в kotlin - PullRequest
0 голосов
/ 10 сентября 2018

Я новичок в программировании, я пытаюсь получить время восхода / захода солнца из API погоды Yahoo и сделать тост на Ui

(я использую библиотеки gson и anko), и это мойкод основной деятельности:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    fetchJson()

}

fun fetchJson(){
   val url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22nome%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"

    val request = Request.Builder().url(url).build()

    val client = OkHttpClient()
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            toast("Failed to execute request")

        }

        override fun onResponse(call: Call?, response: Response?) {
            val body = response?.body()?.string()
            println(body)

            val gson = GsonBuilder().create()
            val Info = gson.fromJson(body, astronomy::class.java)


            runOnUiThread {
//                  info.sunrise is returning null ???????
                toast("this is running from UiThread ${Info.sunrise}")
            }
        }


    })
}
}
class astronomy(val sunrise: String, val sunset: String)

где мне исправить?

Спасибо

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Ответ, который вы получите от этого Yahoo! API намного больше, чем просто раздел астрономии. У вас есть два варианта (один реальный и один временный для проверки):

  • Создайте несколько моделей для анализа всего стека (имеется в виду класс Query со свойствами, такими как count, created, lang и results). Это был бы лучший подход, так как вы будете иметь дело с реальными классами на каждом этапе пути.
data class Query(val count: Int?, val created: String?, val lang: String?, val results: Results?)

data class Results(val channel: Channel?)

//Channel should include more fields for the rest of the data
data class Channel(val astronomy: Astronomy?)

data class Astronomy(val sunrise: String?, val sunset: String?)
  • Бросить всю строку в общий JsonObject (который является классом GSON) и пройти через этот объект (query -> results -> channel -> astronomy -> sunrise и sunset). Это неправильный подход, но он может помочь убедиться, что ваши данные поступают правильно:
val jsonObj: JsonObject = JsonParser().parse(body).asJsonObject

val astronomy = jsonObj
    .getAsJsonObject("query")
    .getAsJsonObject("results")
    .getAsJsonObject("channel")
    .getAsJsonObject("astronomy")

runOnUiThread {
    toast("this is running from UiThread ${astronomy.get("sunrise").asString}")
}
0 голосов
/ 10 сентября 2018

Эй, Эбрахим Хошнуд!

Добро пожаловать в StackOverflow. Кажется, проблема в том, что вы не создали POJO (классы) для родительских объектов астрономии. Если вы хотите разобрать все только с помощью Gson, вам нужно будет создать объекты для «запроса», «результатов», «канала», а затем внутри канала вы можете получить объект астрономии.

Так, например, у вас может быть что-то вроде этого.

class Query(val results: List<Channel>?)
class Channel(val astronomy: astronomy?) // astronomy? is the class you have posted.

и тогда вы могли бы разобрать все, как это

val query = gson.fromJson(body, astronomy::class.java)
val astronomy = query.results?.astronomy
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...