Is this considered to be executed on the main thre...
# android
l
Is this considered to be executed on the main thread? How do you execute a coroutine on the background thread? to be clear
exchangeRepository.getExchanges()
is the call to the
suspend
function.
j
I believe that
viewModelScope
runs by default on
Dispatchers.Main
, so it does run on the main thread. If you want to move the execution context to a background thread you could use
withContext()
c
Yes, this will execute on the main thread as
viewModelScope
uses the
Dispatchers.Main.immediate
dispatcher by default, but this is actually how it should be set up, preferably. The “structured concurrency” expectation is that if any given
suspend
method needs to be executed on a different dispatcher, that it should move itself there, rather than requiring the callers to be on the proper dispatcher. So make sure the API call is done on
<http://Dispatchers.IO|Dispatchers.IO>
internally by wrapping its implementation with
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
, and you shouldn’t have to worry about changing dispatchers for it in the ViewModel
l
so in that case, then is this the correct way to set up the scheduler to be executed on a background thread?
or should it be this?
j
Following Casey's recommendation, you could instead do:
Copy code
ExchangeRepository {
    suspend fun getExchange(...) = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
        ....
    }
}
l
okay so set up the threading in the repository.
gotcha
probably makes sense if you need to invoke that method in multiple places
c
Neither, ideally you’d have
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
in your Repository, not the ViewModel.
Copy code
class ExchangeRepository {
    suspend fun getExchange() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
        // ...
    }
}
l
thanks for the helpful info
i appreciate it
what about if you need to return a value from the repo function?
how do you return within the withContext block?
j
An additional recommendation: to make your repository more testable, you should pass the CoroutineDispatcher as a dependency:
Copy code
class ExchangeRepository(
    private val dispatcher: CoroutineDispatcher = <http://Dispatchers.IO|Dispatchers.IO>
) {
    suspend fun getExchange() = withContext(dispatcher) {
        ...
    }
}
c
It’s a lambda, the last line of the block will be returned from it
l
nevermind … it looks like i just have to remove the
return
keyword
and then whatever is the last statement executed will be returned
thanks again
e
or use
return@withContext
if you want to be explicit