0

I am trying to make a coroutine from a method that I have. to make things simple, let's say I have a class A that I try to connect() and it is connected only after class B that is inside A is connected.

So, I have this code for example, which offcourse doesn't work but it's just to show my use case-

class A {
    fun connect() {
        classB.connect()
        val isConnected = classB.isConnected
    }
}

class B {
    val isConnected: Boolean = false
    fun connect() {
        someObject.connect( SomeListenerInterface {
            override fun onSuccess() {
                isConnected = true
            }
        })
    }
}

I want to make the classB.connect() as a coroutine, and make it suspended, so only when it is done, the line of val isConnected = classB.isConnected would execute and the value would be set properly.

If I would use java and callbacks, I would just pass a callback to the classB.connect() method, and set the class A.isConnected value inside this callback.

is it possible with kotlin coroutines? Thanks

  • The first thing you need here is convert you callback based `someObject.connect` function into a suspend function. You can do that using `suspendCancellableCoroutine` builder. Now that `someObject.connect` is suspend, you need to mark `B.connect` as `suspend`. The last bit required is a `CoroutineScope` which is a bridge between non-coroutine and coroutine based world. Since you haven't provided the exact code and mentioned what it is doing, it's not possible to suggest the coroutine code but what I wrote earlier is the gist of what you need to do. – Arpit Shukla Nov 27 '21 at 17:43
  • @ArpitShukla thanks for the suggestion. I think I will just use something like `val ack = CompletableDeferred()` inside `classB` and I will write `ack.complete(true)` inside `classB.connect()` and in `classA.connect()` I will just do `classB.await()` after the `classB.connect()`. what do you think? – StackerSapper Nov 28 '21 at 10:57
  • @StackerSapper this is unnecessary, you should instead follow what Arpit said, which is detailed in Kirill's answer – Joffrey Dec 06 '21 at 23:32

1 Answers1

3

Convert callback to suspend function using suspendCoroutine. The function below returns true when the connection succeeds:

class B {
    suspend fun connect(): Boolean = suspendCoroutine { continuation ->
        someObject.connect(object : SomeListenerInterface {
            override fun onSuccess() {
                continuation.resume(true)
            }
        })
    }
}

connect function in class A should be suspend respectively:

class A {
    suspend fun connect() {
        val isConnected = classB.connect()
    }
}
Kirill Kitten
  • 1,759
  • 1
  • 4
  • 5
  • thank you, though does the solution with `CompletableDeferred()` isn't good also? because I have many callbacks that are relatd to each other – StackerSapper Dec 07 '21 at 11:54
  • I relied on the [Roman Elizarov](https://stackoverflow.com/users/1051598/roman-elizarov), the Kotlin founder, [opinion](https://stackoverflow.com/questions/48552925/existing-3-function-callback-to-kotlin-coroutines/48562175#48562175). – Kirill Kitten Dec 07 '21 at 13:05