android 如何使用Kotlin从Url中读取JSON?

wgx48brx  于 2023-06-04  发布在  Android
关注(0)|答案(8)|浏览(485)

我正在使用Kotlin开发应用程序。现在我想从服务器获取JSON数据。
在java中,我实现了Asyntask和Rxjava,用于从URL读取JSON。我也在谷歌搜索,但我不能得到我的要求适当的细节。
如何使用Kotlin从Url中读取JSON?

to94eoyn

to94eoyn1#

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

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

关于docs
使用UTF-8或指定的字符集将此URL的整个内容读取为字符串。
不建议在大型文件上使用此方法。
请注意,如果您在Android Activity中使用此方法,则应用会崩溃,因为您使用异步调用阻塞了主线程。为了避免应用程序崩溃,我建议您使用Anko。更准确地说,您只需要添加commons依赖项-而不是整个库-。
您可以找到更多信息in this blog post

2sbarzqh

2sbarzqh2#

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

阅读文本()是Antonio Leiva在他的书Kotlinfor Android Developers中介绍网络时使用的方法(也在博客文章中按照dgrcodeanswer)然而,我不确定是否readText()通常是从URL请求JSON响应的正确方法,因为响应可能非常大(甚至Antonio也提到了Kotlin文档说readText有大小限制的事实)。根据this discussion,您应该使用流而不是readText。我希望看到使用这种方法或任何在Kotlin中最简洁和最优化的方法来回答这个问题,而不添加库依赖项。
参见this thread
还请注意,Antonio在那篇博客文章中提供了readText()不是适当选择的情况下的替代方案。我希望看到有人提供一些明确的时候,它是适当的或不虽然。

hk8txs48

hk8txs483#

试试这个

fun parse(json: String): JSONObject? {
        var jsonObject: JSONObject? = null
        try {
            jsonObject = JSONObject(json)
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        return jsonObject
    }
acruukt9

acruukt94#

最后我从Here得到了答案
使用Retrofit 2.0 RxJava,RxAndroid,KotlinAndroid 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>;
}
i2loujxw

i2loujxw5#

你可以在Kotlin中使用Volley或Retrofit库。实际上你可以在Kotlin中使用所有的Java库。
截击更容易,但改装更快,比截击。你的选择。
Volley Link
Retrofit Link

xam8gpfp

xam8gpfp6#

我有一个fragment_X(class + layout),我想在这里读取在线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())
            }
        }

    }

}
fafcakar

fafcakar7#

您可以使用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)
wqlqzqxt

wqlqzqxt8#

Kotlin中,这很简单。
如果您想从特定URL读取JSON数据。

val jsonData = getJsonDataFromUrl(URL) // Replace with your JSON URL
 val jsonObject = JSONObject(jsonData)

然后简单地创建getJsonDataFromUrl函数。

fun getJsonDataFromUrl(url: String): String {
    val connection = URL(url).openConnection()
    val reader = BufferedReader(InputStreamReader(connection.getInputStream()))
    val jsonData = StringBuilder()

    var line: String?
    while (reader.readLine().also { line = it } != null) {
        jsonData.append(line)
    }
    reader.close()

    return jsonData.toString()
}

相关问题