【问题标题】:How to read JSON from Url using kotlin Android?如何使用 kotlin Android 从 Url 读取 JSON?
【发布时间】:2017-07-03 10:43:06
【问题描述】:

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

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

如何使用 kotlin 从 Url 读取 JSON?

【问题讨论】:

    标签: android kotlin rx-kotlin


    【解决方案1】:

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

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

    来自docs

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

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

    请注意,如果您在 Android 活动中使用它,应用程序会崩溃,因为您正在使用异步调用阻塞主线程。为避免应用程序崩溃,我建议您使用Anko。更准确地说,你只需要add the commons dependency——而不是整个图书馆——。

    您可以找到更多信息in this blog post

    【讨论】:

    • @Paul-Sebastian 不仅回答了这个问题,而且它是唯一一个回答如何在不使用 Java 库的情况下做到这一点的人。它是如何误导的?
    • 对不起,我想上次我尝试了你的答案它没有用,但我不记得究竟是为什么。只是不理我。对不起。
    • 也很抱歉投反对票。也许如果您可以检查您的答案是否有效并对其进行编辑,我可以投票作为交换。
    • 我看到这里的大多数人只阅读您答案中的代码,而不是回答本身。在您对这个精彩的答案投反对票之前,只需阅读“更多信息”!
    • Anko 库现已弃用,因此请更新您的评论。
    【解决方案2】:

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

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

    另见this thread

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

    【讨论】:

    • 这是一个很好的解决方案。谢谢!!
    【解决方案3】:

    试试这个

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

    【讨论】:

    • 现有的 Android 库与 Kotlin 兼容,您可以进行改造或选择获取数据。
    【解决方案4】:

    终于得到Here的答复

    使用 Retrofit 2.0 读取 Json 数据 RxJava, RxAndroid, Kotlin Android 扩展。

      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>;
    }
    

    【讨论】:

      【解决方案5】:

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

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

      Volley Link

      Retrofit Link

      【讨论】:

        【解决方案6】:

        我有一个 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())
                    }
                }
        
            }
        
        }
        

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            猜你喜欢
            • 2015-01-20
            • 1970-01-01
            • 2019-11-19
            • 1970-01-01
            • 1970-01-01
            • 2021-04-09
            • 2022-12-05
            • 2023-03-21
            • 1970-01-01
            相关资源
            最近更新 更多