Reputation: 407
What is the correct way to call the OkHTTP client inside a Coroutine?
CoroutineScope(IO).launch {
val request = Request.Builder()
.url("${host}/dots")
.build()
val client = OkHttpClient()
client.newCall(request).enqueue(object: Callback{
override fun onFailure(call: Call, e: IOException) {
isConnected.postValue(false)
}
override fun onResponse(call: Call, response: Response) {
val loadingStr = response.body()?.string().toString()
loadingStrings = loadingStr
Log.i("My_Error",loadingStrings)
}
})
}
In the onResponse the loadingStr variable shows warning for string() saying inappropriate blocking method called. Please tell me the correct way to do the same.
Upvotes: 9
Views: 12789
Reputation: 13448
OkHttp provides two modes of concurrency
Outside of these most frameworks you use will have bridge methods that convert between different modes and difference frameworks.
You should use a library like https://github.com/gildor/kotlin-coroutines-okhttp to do it for you. This code needs to do the basic normal path but also specifically needs to handle errors and separately cancellation. Your code inside coroutines should never be calling enqueue directly.
suspend fun main() {
// Do call and await() for result from any suspend function
val result = client.newCall(request).await()
println("${result.code()}: ${result.message()}")
}
This is another example from the Coil image loading library which as a framework makes sense to implement this itself rather than using a library
internal suspend inline fun Call.await(): Response {
return suspendCancellableCoroutine { continuation ->
val callback = ContinuationCallback(this, continuation)
enqueue(callback)
continuation.invokeOnCancellation(callback)
}
}
OkHttp can't implement this directly for at least two reasons
Upvotes: 19