2

我是 Kotlin 的新手,我找到了 Klaxon 库来解析 JSON。我找不到如何执行 url( http://localhost:8080/items/2 )、读取 JSON 字符串并将数据保存到变量并将它们打印到控制台。CreatedAt 和 UpdatedAt 我不需要保存。

来自网址的 JSON:

{
    "brand": "Ferrero",
    "name": "Nutella",
    "healthy": false,
    "date": "2017-03-14T00:00:00.000Z",
    "id": 2,
    "createdAt": "2018-03-14T13:33:22.000Z",
    "updatedAt": "2018-03-20T21:23:44.000Z"
}

代码:

class DetailItem : AppCompatActivity()  {
    var itemId : String = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail_item)
        itemId = intent.getStringExtra("itemId")
    }

    override fun onResume() {
        super.onResume()
        example()
    }

    private fun parse(name: String) : Any{
        val cls = Parser::class.java
        val inputStream = cls.getResourceAsStream(name)!!
        return Parser().parse(inputStream)!!
    }

    private fun example(){
        val url = "http://192.168.99.100:8080/items/" + itemId
        val obj = parse("url") as JsonObject

        val brand = obj.string("brand")
        val name = obj.string("name")
        println(brand + name)
    }
4

2 回答 2

1

问题是方法cls.getResourceAsStream(name)返回null,并且!!操作符导致 NPE 被抛出。

为什么cls.getResourceAsStream(name)返回null?发生这种情况是因为方法在您在项目中提供的资源中getResourceAsStream搜索具有提供的资源(即文件) 。name

但是,在您的情况下,您想从 URL 下载 JSON,因此您需要首先执行下载,这将为您提供格式为String(或可以转换为 a 的内容String)的 JSON,然后解析该字符串与Parser().parse(yourJsonString) as JsonObject.

编辑

这是一个使用 OkHttp 库的示例:

import com.beust.klaxon.Klaxon
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException

fun main(args: Array<String>) {
    val url = "https://jsonplaceholder.typicode.com/posts/1"

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

    println(Thread.currentThread())
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            e?.printStackTrace()
        }

        override fun onResponse(call: Call?, response: Response) {
            if (!response.isSuccessful) {
                System.err.println("Response not successful")
                return
            }
            val json = response.body()!!.string()
            val myData = Klaxon().parse<MyData>(json)
            println("Data = $myData")
            println(Thread.currentThread())
        }

    })
    // Shutdown the executor as soon as the request is handled
    client.dispatcher().executorService().shutdown()
}

data class MyData(val title: String, val userId: Int)

REST API 返回的 JSON 字符串是:

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipitsuscipit recusandae consequuntur expedita et cumreprehenderit molestiae ut ut quas totamnostrum rerum est autem sunt rem eveniet architecto"
}

该代码打印:

Thread[main,5,main]
Data = MyData(title=sunt aut facere repellat provident occaecati excepturi optio reprehenderit, userId=1)
Thread[OkHttp https://jsonplaceholder.typicode.com/...,5,main]

请注意,onResponse回调在工作线程上执行,而不是在主线程上执行,因此如果您在 Android 中使用此代码,您将无法从那里更改 UI 元素(除非您使用runOnUiThread()或类似技术)

于 2018-03-21T10:42:18.347 回答
1

我发现这段代码可以解决我的问题。但它是 AsyncTask,如何重写它并仅在我想要的时候执行它?

inner class AsyncTaskHandleJson : AsyncTask<String, String, String>() {
        override fun doInBackground(vararg url: String?): String {

            var text: String
            var connection = URL(url[0]).openConnection() as HttpURLConnection
            try {
                connection.connect()
                text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
            } finally {
                connection.disconnect()
            }

            return text
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            handleJson(result)
        }
    }

    private fun handleJson(jsonString: String?) {

        val jsonObject = JSONObject(jsonString)

        val itemIdBrand = findViewById<TextView>(R.id.itemIdBrand)
        itemIdBrand.text = jsonObject.getString("brand")

        println(jsonObject.getString("brand"))
    }
于 2018-03-21T11:56:42.070 回答