如何在 Kotlin 中创建异步 post 请求?
How can I create an asynchronous post request in Kotlin?
我正在尝试向服务器发送 POST 请求并获取一些数据。我在主线程上尝试 运行ning 请求,但它一直给我一个错误,所以我决定使用 coroutines
到 运行 它作为异步线程。这是我目前所拥有的:
class requests{
private val client = OkHttpClient()
fun run() = runBlocking {
launch {
val postBody = """
|Releases
|--------
|
| * _1.0_ May 6, 2013
| * _1.1_ June 15, 2013
| * _1.2_ August 11, 2013
|""".trimMargin()
val request = Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
println(response.body!!.string())
}
}
}
companion object {
val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
}
}
当我 运行 requests().run()
我得到以下错误:
android.os.NetworkOnMainThreadException
我不确定为什么会收到此错误,我认为 coroutines
创建了一个新线程来防止这种情况发生。
runBlocking
不会切换线程,所以如果你在主线程上调用它,协程也会在主线程上启动。此方法会阻塞当前线程,因此切勿在生产中使用它:阻塞线程的性能非常低,您应该创建一个新协程并在那里启动您的代码
协程本身可以在主线程上正常工作,但您的代码 运行 可以检查当前线程,以及在这种情况下会发生什么 - 它会抛出异常
以下代码应该适合您:
class requests{
private val client = OkHttpClient()
private val coroutineScope = CoroutineScope(Dispatchers.Default)
fun run() {
coroutineScope.launch {
val postBody = """
|Releases
|--------
|
| * _1.0_ May 6, 2013
| * _1.1_ June 15, 2013
| * _1.2_ August 11, 2013
|""".trimMargin()
val request = Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
println(response.body!!.string())
}
}
}
companion object {
val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
}
}
另一种方法是使 run
成为一个 suspend
函数并从外部协程 运行 它 - 如果您想 return 你的电话结果
我正在尝试向服务器发送 POST 请求并获取一些数据。我在主线程上尝试 运行ning 请求,但它一直给我一个错误,所以我决定使用 coroutines
到 运行 它作为异步线程。这是我目前所拥有的:
class requests{
private val client = OkHttpClient()
fun run() = runBlocking {
launch {
val postBody = """
|Releases
|--------
|
| * _1.0_ May 6, 2013
| * _1.1_ June 15, 2013
| * _1.2_ August 11, 2013
|""".trimMargin()
val request = Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
println(response.body!!.string())
}
}
}
companion object {
val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
}
}
当我 运行 requests().run()
我得到以下错误:
android.os.NetworkOnMainThreadException
我不确定为什么会收到此错误,我认为 coroutines
创建了一个新线程来防止这种情况发生。
runBlocking
不会切换线程,所以如果你在主线程上调用它,协程也会在主线程上启动。此方法会阻塞当前线程,因此切勿在生产中使用它:阻塞线程的性能非常低,您应该创建一个新协程并在那里启动您的代码
协程本身可以在主线程上正常工作,但您的代码 运行 可以检查当前线程,以及在这种情况下会发生什么 - 它会抛出异常
以下代码应该适合您:
class requests{
private val client = OkHttpClient()
private val coroutineScope = CoroutineScope(Dispatchers.Default)
fun run() {
coroutineScope.launch {
val postBody = """
|Releases
|--------
|
| * _1.0_ May 6, 2013
| * _1.1_ June 15, 2013
| * _1.2_ August 11, 2013
|""".trimMargin()
val request = Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
println(response.body!!.string())
}
}
}
companion object {
val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
}
}
另一种方法是使 run
成为一个 suspend
函数并从外部协程 运行 它 - 如果您想 return 你的电话结果