You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio Kotlin中解析OpenWeatherMap API JSON字段问题

解决Kotlin中解析OpenWeatherMap JSON额外字段的问题

嘿,作为Android Studio Kotlin新手,你已经搞定了weather数组的解析,距离拿到所有需要的字段只差几步啦!下面我会一步步教你如何获取country、name这些字段,还有其他常用的嵌套数据:

1. 解析顶层字段(比如城市名name)

像name、cod、visibility这类直接在JSON最外层的字段,你可以直接从最开始创建的jsonObject中获取:

val cityName = jsonObject.optString("name") // 拿到Bilbao
val visibility = jsonObject.optInt("visibility") // 拿到10000

2. 解析嵌套对象中的字段(比如sys里的country)

对于sys、main这种嵌套的JSON对象,你需要先获取对应的子JSONObject,再从中提取字段。这里要注意空安全,用?.安全调用避免空指针:

// 获取sys对象里的国家码
val sysObj = jsonObject.optJSONObject("sys")
val countryCode = sysObj?.optString("country") // 拿到ES

// 获取main对象里的温度等数据
val mainObj = jsonObject.optJSONObject("main")
val temp = mainObj?.optDouble("temp") // 拿到60.69
val humidity = mainObj?.optInt("humidity") // 拿到100

3. 修改你的完整代码

我帮你调整了原代码,修复了变量名冲突(循环里的jsonObject改成了weatherObj,避免覆盖外层对象),并加入了所有你需要的字段解析:

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)
        val textView = findViewById(R.id.txtView) as TextView // 把TextView初始化移到外面,避免重复查找

        doAsync(executorService = executor) {
            val result = URL("https://api.openweathermap.org/data/2.5/weather?q=Bilbao,spain&units=imperial&APPID=-------------").readText()
            
            uiThread {
                val data = StringBuilder()
                val jsonObject = JSONObject(result)

                // 解析顶层字段:城市名
                val cityName = jsonObject.optString("name")
                data.append("城市: ").append(cityName).append("\n")

                // 解析sys对象里的国家码
                val sysObj = jsonObject.optJSONObject("sys")
                val countryCode = sysObj?.optString("country") ?: "未知" // 用?:给默认值
                data.append("国家: ").append(countryCode).append("\n")

                // 解析weather数组
                val jsonArray = jsonObject.optJSONArray("weather")
                if (jsonArray != null && jsonArray.length() > 0) {
                    for (i in 0 until jsonArray.length()){
                        val weatherObj = jsonArray.getJSONObject(i) // 重命名变量避免冲突
                        val main = weatherObj.optString("main")
                        val desc = weatherObj.optString("description")
                        val icon = weatherObj.optString("icon")
                        data.append("天气状况: ").append(main).append(" - ").append(desc).append(" (图标: ").append(icon).append(")\n")
                    }
                }

                // 解析main对象里的温度数据
                val mainObj = jsonObject.optJSONObject("main")
                val temp = mainObj?.optDouble("temp") ?: 0.0
                val humidity = mainObj?.optInt("humidity") ?: 0
                data.append("当前温度: ").append(temp).append("°F\n")
                data.append("湿度: ").append(humidity).append("%")

                textView.text = data.toString()
            }
        }
    }
}

几个小提示

  • 变量名冲突:原代码中循环里的jsonObject会覆盖外层的jsonObject,这会导致后续无法访问顶层字段,所以我改成了weatherObj
  • 空安全处理:用?.安全调用和?: Elvis操作符给字段设置默认值,避免API返回null时崩溃
  • UI元素初始化:把TextView的初始化移到doAsync外面,避免在后台线程和UI线程重复查找控件

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:27:35