Sunday, 21 February 2021

Kotlin Flow: callbackFlow with lazy initializer of callback object

I want to use reactive paradigm using Kotlin Flow in my Android project. I have an external callback-based API so my choice is using callbackFlow in my Repository class.

I've already read insightfully some proper docs with no help:

What I want to achieve:

Currently my Repository class looks like this (simplified code):

lateinit var callback: ApiCallback

fun someFlow() = callbackFlow<SomeModel> {
    callback = object : ApiCallback {
        override fun someApiMethod() {
            offer(SomeModel())
        }
    }

    awaitClose { Log.d("Suspending flow until methods aren't invoked") }
}

suspend fun someUnfortunateCallbackDependentCall() {
    externalApiClient.externalMethod(callback)
}

Problem occurs when someUnfortunateCallbackDependentCall is invoked faster than collecting someFlow(). For now to avoid UninitializedPropertyAccessException I added some delays in my coroutines before invoking someUnfortunateCallbackDependentCall but it is kind of hack/code smell for me.

My first idea was to use by lazy instead of lateinit var as this is what I want - lazy initialization of callback object. However, I couldn't manage to code it altogether. I want to emit/offer/send some data from someApiMethod to make a data flow but going outside of callbackFlow would require ProducerScope that is in it. And on the other hand, someUnfortunateCallbackDependentCall is not Kotlin Flow-based at all (could be suspended using Coroutines API at best).

Is it possible to do? Maybe using some others Kotlin delegates? Any help would be appreciated.



from Kotlin Flow: callbackFlow with lazy initializer of callback object

No comments:

Post a Comment