首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin HTTP请求

Kotlin HTTP请求
EN

Stack Overflow用户
提问于 2021-09-06 16:28:12
回答 4查看 383关注 0票数 1
代码语言:javascript
复制
@SuppressLint("SetTextI18n")
fun wordCall() {
    val textView: TextView = findViewById(R.id.blue)
    val client = OkHttpClient()
    val url = URL("https://reqres.in/api/users?page=2")
    val request = Request.Builder()
        .url(url)
        .get()
        .build()
    val response = client.newCall(request).execute()
    val responseBody = response.body!!.string()
    //Response
    textView.text = "Response Body: $responseBody"
}
}

我是kotlin的新手,正在努力做一个网络请求,我正在使用okhttp,而我在logcat中得到的错误是java.lang.RuntimeException : Unable to start activity android.os.NetworkOnMainThreadException

EN

回答 4

Stack Overflow用户

发布于 2021-09-06 16:38:26

你的异常实际上会告诉你你到底做错了什么。您没有使用其他线程来执行NetworkOperations。相反,你在你的UI-Thread上执行网络操作,这在Android上不能(不)工作。

连接到url的代码应该在UI线程之外的AsyncTasks doInBackground()方法中执行。

看一下这个关于如何使用AsyncTask的问题:How to use AsyncTask

票数 1
EN

Stack Overflow用户

发布于 2021-09-06 18:33:58

Okhttp是异步的,因此您应该创建一个新的Trhead来显示响应:

代码语言:javascript
复制
 client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
    // Handle this
}

override fun onResponse(call: Call, response: Response) {
    // here is the response from the server
}

})

票数 0
EN

Stack Overflow用户

发布于 2021-09-06 18:46:29

是的,根据文档,你是对的-

默认情况下,

安卓应用程序完全在单线程上运行,即“UI线程”(或“主线程”)。这意味着您的应用程序在UI线程中执行的任何操作都需要很长时间才能完成。

因此,在UI线程中运行的任何方法都应该在该线程上做尽可能少的工作。特别是,在关键的生命周期方法中设置的活动应该尽可能少,比如onCreate()和onResume()。可能长时间运行的操作,如网络或数据库操作,或计算代价高昂的计算,如调整位图大小,应该在工作线程中完成(对于数据库操作,则通过异步请求)。

虽然您可以通过授予StrictMode ThreadPolicy权限来调用wordCall方法,但只能将其用于调试目的。

代码语言:javascript
复制
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_create_account)

        val policy = ThreadPolicy.Builder()
            .permitAll().build()
        StrictMode.setThreadPolicy(policy)

        //call method now
    }

我认为我在正确的轨道上,我相信错误是我需要使用runOnUiThread,但我不确定如何实现它。

基于你的想法,我正在分享示例代码,你可以检查-我们将使用定时器的schedule方法来调度任务,并通过runOnUiThread检索响应正文并将结果文本设置为文本视图。

这就是-

代码语言:javascript
复制
    package com.example.kotlin

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import okhttp3.OkHttpClient
import okhttp3.Request
import java.lang.Exception
import java.net.URL
import java.util.*
import android.app.Activity
import android.content.Context

class CreateAccount : AppCompatActivity() {

    lateinit var textView: TextView
    var timer = Timer()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_create_account)

       
        timer.schedule(WordCall(this), 0, (30 * 60 * 1000).toLong())


    }



}

class WordCall(val context: Context) : TimerTask() {
    override fun run() {
        val textView: TextView = (context as Activity).findViewById(R.id.blue)
        val client = OkHttpClient()
        val url = URL("https://reqres.in/api/users?page=2")

        val request = Request.Builder()
            .url(url)
            .get()
            .build()

        try {
            val response = client.newCall(request).execute()
            val responseBody = response.body()!!.string()
            (context as Activity).runOnUiThread {
                textView.text = "Response Body: $responseBody"
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69077741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档