提问人:Legendary 提问时间:1/4/2022 最后编辑:SergioLegendary 更新时间:10/26/2022 访问量:1988
Kotlin OkHTTP android.os.NetworkOnMainThreadException
Kotlin OkHTTP android.os.NetworkOnMainThreadException
问:
我正在使用 kotlin 发送 http 请求并收到此错误
错误:java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx/xxx.android.ui.xxx}: android.os.NetworkOnMainThreadException
附加信息:GET 请求需要首先工作。因为该过程根据 URL 的响应进行。
我的代码:
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme_MainActivity)
super.onCreate(savedInstanceState)
val request = Request.Builder()
.url("https://publicobject.com/helloworld.txt")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
}
}
答:
3赞
Sergio
1/4/2022
#1
Android 主要组件(如 等)在主线程中运行。您无法在主线程中发出网络请求(或其他可能长时间运行的操作)。您需要在 background(worker) 线程中安排它。通过使用方法,您可以同步发送请求。即在主线程中。
您可以使用方法异步发送请求:Activities
BroadcastReceiver
Call.execute()
Call.enqueue()
client.newCall(request).enqueue(object : Callback<Response> {
override fun onResponse(call: Call<Response>, response: Response<Response>
) {
// handle response
}
override fun onFailure(call: Call<ApiResponse>, t: Throwable) {
// handle error
}
})
还有另一种使用 Kotlin 协程发出和处理请求的方法:
// suspendCoroutine - suspends a coroutine until request is executed
suspend fun makeRequest(): String = suspendCoroutine { continuation ->
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
continuation.resumeWithException(e) // resume calling coroutine
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
response.use {
continuation.resume(response.body!!.string()) // resume calling coroutine
}
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
// ...
lifecycle.coroutineScope.launch { // launching a coroutine
val result = makeRequest()
// do something with result
// save to Preferences
getPreferences(MODE_PRIVATE).edit().putString("val001", result).apply(); //save prefences
println("Request complete")
}
}
评论