@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。
发布于 2021-09-06 16:38:26
你的异常实际上会告诉你你到底做错了什么。您没有使用其他线程来执行NetworkOperations。相反,你在你的UI-Thread上执行网络操作,这在Android上不能(不)工作。
连接到url的代码应该在UI线程之外的AsyncTasks doInBackground()方法中执行。
看一下这个关于如何使用AsyncTask的问题:How to use AsyncTask
发布于 2021-09-06 18:33:58
Okhttp是异步的,因此您应该创建一个新的Trhead来显示响应:
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
}})
发布于 2021-09-06 18:46:29
是的,根据文档,你是对的-
默认情况下,
安卓应用程序完全在单线程上运行,即“UI线程”(或“主线程”)。这意味着您的应用程序在UI线程中执行的任何操作都需要很长时间才能完成。
因此,在UI线程中运行的任何方法都应该在该线程上做尽可能少的工作。特别是,在关键的生命周期方法中设置的活动应该尽可能少,比如onCreate()和onResume()。可能长时间运行的操作,如网络或数据库操作,或计算代价高昂的计算,如调整位图大小,应该在工作线程中完成(对于数据库操作,则通过异步请求)。
虽然您可以通过授予StrictMode ThreadPolicy权限来调用wordCall方法,但只能将其用于调试目的。
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检索响应正文并将结果文本设置为文本视图。
这就是-
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()
}
}
}https://stackoverflow.com/questions/69077741
复制相似问题