8

我正在使用 kotlin 开发应用程序。现在我想从服务器获取 JSON 数据。

在 java 中,我实现了 Asyntask 以及 Rxjava,用于从 Url 读取 JSON。我也在谷歌搜索,但我无法获得适合我要求的详细信息。

如何使用 kotlin 从 Url 读取 JSON?

4

7 回答 7

14

我猜您正在尝试从服务器 API 读取响应,您希望它是带有 JSON 的字符串。为此,您可以使用:

val apiResponse = URL("yourUrl").readText()

文档

使用 UTF-8 或指定的字符集将此 URL 的全部内容作为字符串读取。

不建议在大文件上使用此方法。

请注意,如果您在 Android 活动中使用它,应用程序会崩溃,因为您正在使用异步调用阻塞主线程。为了避免应用程序崩溃,我建议您使用Anko。更准确地说,您只需要添加公共依赖项——而不是整个库——。

您可以在此博客文章中找到更多信息

于 2017-08-23T16:49:20.310 回答
5

更新/注意:我已经写了一个关于这个主题的完整的一步一步的教程,在这里。虽然由您决定使用什么第三方库(其他答案中提到了一些),但到目前为止,Retrofit 是目前使用的事实上的标准。此外,它还内置了对协程的支持。如果您使用协程而不是旧的回调方法,您的网络代码应该是异步的,并且您的代码将更干净、更易于遵循和调试等。上述教程甚至向您展示了如何轻松地从回调更新旧代码以使用协程。

readText() 是 Antonio Leiva 在他的 Kotlin for Android Developers 一书中介绍网络时使用的方法(以及根据dgrcode回答在博客文章中)但是我不确定 readText() 是否是正确的方法用于从 URL 请求 JSON 响应,因为响应可能非常大(甚至 Antonio 提到确认 Kotlin 文档说 readText 有大小限制的事实)。根据这个讨论,您应该使用流而不是 readText。我希望看到使用该方法或 Kotlin 中最简洁和最佳的方法对此答案的响应,而不添加库依赖项。

另请参阅此线程

还要注意,当readtext()不是适当的选择时,安东尼奥确实在该博客文章中提供了替代方案。我很乐意看到有人提供一些关于何时合适或不合适的说明。

于 2017-12-17T23:57:39.250 回答
4

尝试这个

fun parse(json: String): JSONObject? {
        var jsonObject: JSONObject? = null
        try {
            jsonObject = JSONObject(json)
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        return jsonObject
    }
于 2017-07-03T11:05:40.420 回答
4

终于从这里得到答案

使用 Retrofit 2.0 RxJava、RxAndroid、Kotlin Android Extensions 读取 Json 数据。

  fun provideRetrofit(): Retrofit {
    return Retrofit.Builder()
            .baseUrl("https://www.example.com")
            .addConverterFactory(MoshiConverterFactory.create())
            .build()
    }

模块

interface  Api {
@GET("/top.json")
fun getTop(@Query("after") after: String,
           @Query("limit") limit: String): Call<NewsResponse>;
}
于 2017-07-03T12:46:36.677 回答
1

您可以在 Kotlin 中使用 Volley 或 Retrofit 库。实际上您可以在 Kotlin 中使用所有 Java 库。

Volley 比 Volley 更容易,但改造速度更快。您的选择。

排球链接

改造链接

于 2017-07-03T11:33:41.623 回答
0

我有一个 fragment_X(类 + 布局),我想在其中读取在线 Json 文件(您也可以读取 txt 文件),并将内容显示给 TextView。

==> 注意:赋予应用程序在 Manifest 中访问互联网的权利。

class Fragment_X: Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_X, container, false)

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if(isNetworkAvailable()) {
            val myRunnable = Conn(mHandler)
            val myThread = Thread(myRunnable)
            myThread.start()
        }
    }


    // create a handle to add message
    private val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(inputMessage: Message) { if (inputMessage.what == 0) {
            textView.text = inputMessage.obj.toString() }
        } }

    // first, check if network is available.
    private fun isNetworkAvailable(): Boolean { val cm = requireActivity().getSystemService(
        Context.CONNECTIVITY_SERVICE
    ) as ConnectivityManager
        return cm.activeNetworkInfo?.isConnected == true
    }


    //create a worker with a Handler as parameter
    class Conn(mHand: Handler): Runnable {
        val myHandler = mHand
        override fun run() {
            var content = StringBuilder()
            try {
                // declare URL to text file, create a connection to it and put into stream.
                val myUrl = URL("http:.........json")  // or URL to txt file
                val urlConnection = myUrl.openConnection() as HttpURLConnection
                val inputStream = urlConnection.inputStream

                // get text from stream, convert to string and send to main thread.
                val allText = inputStream.bufferedReader().use { it.readText() }
                content.append(allText)
                val str = content.toString()
                val msg = myHandler.obtainMessage()
                msg.what = 0
                msg.obj = str
                myHandler.sendMessage(msg)
            } catch (e: Exception) {
                Log.d("Error", e.toString())
            }
        }

    }

}
于 2019-09-29T09:48:06.790 回答
0

您可以使用 RequestQueue:https ://developer.android.com/training/volley/requestqueue

val textView = findViewById<TextView>(R.id.text)
// ...

// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(this)
val url = "https://www.google.com"

// Request a string response from the provided URL.
val stringRequest = StringRequest(Request.Method.GET, url,
        Response.Listener<String> { response ->
            // Display the first 500 characters of the response string.
            textView.text = "Response is: ${response.substring(0, 500)}"
        },
        Response.ErrorListener { textView.text = "That didn't work!" })

// Add the request to the RequestQueue.
queue.add(stringRequest)
于 2020-08-02T18:46:28.993 回答