Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using OkHTTPClient() inside a coroutine always throws warning "inappropriate blocking method called"

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.

like image 823
gg-dev-05 Avatar asked Jun 15 '20 05:06

gg-dev-05


People also ask

How do I fix inappropriate blocked call?

Wrap the "inappropriate blocking method call" code in another context using withContext . This will suspend the current coroutine, then execute the "inappropriate blocking call" on a different thread (from either the Dispatchers.IO or Dispatchers.

Are coroutines blocking?

Coroutines are more efficient than threads because they are suspended and resumed instead of blocking execution. However, we need to block threads in some specific use cases. For example, in the main() function, we need to block the thread, otherwise, our program will end without waiting for the coroutines to complete.

What is Okhttpclient Kotlin?

OkHttp is an efficient HTTP & HTTP/2 client for Android and Java applications. It comes with advanced features, such as connection pooling (if HTTP/2 isn't available), transparent GZIP compression, and response caching, to avoid the network completely for repeated requests.

What are coroutines Kotlin?

A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages.

What is the use of delay in Kotlin coroutine?

Kotlin Coroutines on Android Suspend Function In Kotlin Coroutines As it is known that when the user calls the delay () function in any coroutine, it will not block the thread in which it is running, while the delay () function is called one can do some other operations like updating UI and many more things.

Can I use oncreate () function from a coroutine?

This function should not be used from a coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests. override fun onCreate (savedInstanceState: Bundle?) { Log-Output of the above program (Timestamps in seconds is shown by Oval Circle in image)

How do you handle exceptions in coroutines?

Coroutines use the regular Kotlin syntax for handling exceptions: try/catch or built-in helper functions like runCatching (which uses try/catch internally). We said before that uncaught exceptions will always be thrown. However, different coroutines builders treat exceptions in different ways.

How to define a coroutineexceptionhandler?

Here’s how you can define a CoroutineExceptionHandler, whenever an exception is caught, you have information about the CoroutineContext where the exception happened and the exception itself: When ⏰: The exception is thrown by a coroutine that automatically throws exceptions (works with launch, not with async ).


1 Answers

OkHttp provides two modes of concurrency

  1. Synchronous blocking via execute
  2. Asynchronous non-blocking via enqueue

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

https://github.com/coil-kt/coil/blob/0af5fe016971ba54518a24c709feea3a1fc075eb/coil-base/src/main/java/coil/util/Extensions.kt#L45-L51

internal suspend inline fun Call.await(): Response {
    return suspendCancellableCoroutine { continuation ->
        val callback = ContinuationCallback(this, continuation)
        enqueue(callback)
        continuation.invokeOnCancellation(callback)
    }
}

https://github.com/coil-kt/coil/blob/a17284794764ed5d0680330bfd8bca722a36bb5e/coil-base/src/main/java/coil/util/ContinuationCallback.kt

OkHttp can't implement this directly for at least two reasons

  1. It would add a dependency Kotlin coroutines library, and require more secondary releases.
  2. This problem isn't specific to Kotlin coroutines, so OkHttp would have code to deal with RxJava 1/2/3, Spring Reactor, KTor etc.
like image 184
Yuri Schimke Avatar answered Sep 24 '22 09:09

Yuri Schimke