【问题标题】:How to parse an irregular JSON string from an API如何从 API 解析不规则的 JSON 字符串
【发布时间】:2021-01-24 12:06:51
【问题描述】:

您好,我是 Android Studio Kotlin 的新手,我遇到了这个问题:我有一个由 OpenWeatherMap API 返回的 JSON 字符串。过去link 提出了类似的问题,但它是 Java。

This is a typical string:

 {
    "coord": {
        "lon": -2.93,
        "lat": 43.26
    },
    "weather": [{
        "id": 801,
        "main": "Clouds",
        "description": "few clouds",
        "icon": "02n"
    }],
    "base": "stations",
    "main": {
        "temp": 60.69,
        "feels_like": 62.33,
        "temp_min": 59,
        "temp_max": 63,
        "pressure": 1023,
        "humidity": 100
    },
    "visibility": 10000,
    "wind": {
        "speed": 3.36,
        "deg": 120
    },
    "clouds": {
        "all": 20
    },
    "dt": 1602195029,
    "sys": {
        "type": 1,
        "id": 6395,
        "country": "ES",
        "sunrise": 1602224311,
        "sunset": 1602265138
    },
    "timezone": 7200,
    "id": 3128026,
    "name": "Bilbao",
    "cod": 200
}

这是我的代码:

package com.example.downloadtest

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import org.json.JSONObject
import java.net.URL
import java.util.concurrent.Executors

val executor = Executors.newScheduledThreadPool(5)



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

        doAsync(executorService = executor) {
            //val result = URL("https://httpbin.org/get").readText()
            val result = URL("https://api.openweathermap.org/data/2.5/weather?q=Bilbao,spain&units=imperial&APPID=-------------").readText()
            val textView = findViewById(R.id.txtView) as TextView
            uiThread {
                //textView.setText(result)
                println(result)
                //toast(result)
                val data = StringBuilder()
                val jsonObject = JSONObject(result)
                val jsonArray = jsonObject.optJSONArray("weather")
                println(jsonArray)
                for (i in 0 until jsonArray.length()){
                    val jsonObject = jsonArray.getJSONObject(i)
                    val main = jsonObject.optString("main").toString()
                    val desc = jsonObject.optString("description").toString()
                    val icon = jsonObject.optString("icon").toString()
                    data.append("Bilbao Weather: \n").append(main).append(" : ").append(desc).append(" : ").append(icon)
                    textView.text = data.toString()
                }
            }
        }

    }

}

如您所见,我可以解析字符串的一部分,但无法解析其他任何内容。如果我想解析“国家”或“名称”,我该怎么做?

在此先感谢您的帮助。

雷。

【问题讨论】:

    标签: json android-studio kotlin anko


    【解决方案1】:

    您的 json 由嵌套对象组成。如果不访问对象本身,就无法访​​问对象的内部。

    如果要访问description 参数,首先需要将weather 设为对象。 country 也一样,您需要从 sys 创建一个对象。

    你会这样做:

    val sys: JSONObject? = jsonObject.optJSONObject("sys") //this can be null (I don't know how consistent is that model)
    val country = sys?.optString("country") ?: "" //if sys is null, default to empty string
    

    至于名字,那是初始对象的一个​​属性,因此可以很容易地这样访问:

    val name = jsonObject.optString("name")
    

    需要考虑的一点是:你为什么在String 上做.toString()

    函数optString("fieldName", "fallback") 将始终返回一个String,如果你提供了一个回退,它将使用它,否则它将返回一个空的String

    您还应该考虑(从长远来看)如果您想创建一个对该 json 进行建模的对象,并将其映射到 jackson 或任何其他库,那么您将像访问任何其他 java/kotlin 参数一样访问它们。

    【讨论】:

    • 一切都如你所说。我会记下它,因为在这里我拥有我希望遇到的大部分内容。谢谢亚历克斯
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 2019-09-24
    相关资源
    最近更新 更多