How to return callback/stream to the caller thread?

861 views Asked by At

I have some class 'A', the internal work of which is performed using rx or coroutines with flows. Class 'A' should not return any instances of rx/coroutines (and flows), their work should be hidden, we need Future result for callbacks and observe on custom Observer.

Caller class 'B' can call A's methods on the main(UI) thread or another thread. If the methods are called on Ui thread, it's easy because we can observe on Main thread and use corresponding coroutine scope.

But how do we deal with this situation if the caller's thread is not main?

2

There are 2 answers

0
Petrus Nguyễn Thái Học On

Use Handler

class A {
    private val mainHandler = Handler(Looper.getMainLooper())

    fun <T> observe(onChanged: (T) -> Unit) {
       ...
       mainHandler.post { onChanged(value) }
    }
}
0
Bram Stoker On

How do your classes A and B look like?

But how do we deal with this situation if the caller's thread is not main?

If your code in B is ran in a coroutine, then use withContext() and just make the call on the main thread:

class B(private val a: A) {

    fun doStuffIn(scope: CoroutineScope) {
        scope.launch {
            ...
            withContext(Dispatchers.Main) {
                a.collectData()
            }
        }
    }

    // or:
    fun CoroutineScope.doStuff() {
        launch {
            ...
            withContext(Dispatchers.Main) {
                a.collectData()
            }
        }
    }
    
    // or:
    suspend fun doStuff2() {
        ...
        withContext(Dispatchers.Main) {
            a.collectData()
        }
    }
}