Reputation: 1326
As attached, the code (from Kodeco at here) is in an Android Fragment, I was wondering what's the relationship of Dispatchers.Main
between these two lines:
L63: private val coroutineScope = CoroutineScope(Dispatchers.Main + parentJob)
L68: coroutineScope.launch(Dispatchers.Main) { .. }
What by my understanding is, the Dispatchers.Main
on L63 means the coroutineScope is bound to Main thread, and the Dispatchers.Main
on L68 means the coroutine block will be run in Main thread.
But do I have to specify it twice? What if I don't do like this, for example, what happens if I change L68 to be like: coroutineScope.launch {..}
Upvotes: 2
Views: 1022
Reputation: 1326
Sorry for this dumb question, I got it now like below:
L63: private val coroutineScope = CoroutineScope(Dispatchers.Main + parentJob)
This specifies a custom coroutine scope, and this scope has been bound to the Dispatchers.Main (the main thread, and let's ignore parentJob in this question).
has bound to Dispatchers.Main
means: the coroutine started by this scope will run in main thread.
And on L68:
L68: coroutineScope.launch(Dispatchers.Main) { .. }
this specifies, again, the coroutine block will run in main thread.
So as for the again
here, I mean, by looking into the source code of launch
function, I found this:
val newContext = newCoroutineContext(context)
And there is a context combination in the function of newCoroutineContext(context)
which looks like:
val combined = coroutineContext + context
which means add the L68's Dispatchers.Main
onto the L63's Dispatchers.Main
, owing to they are the same, so finally the coroutine block after L68 will run in the main thread.
So to answer my question: what happens if I change L68 to be like: coroutineScope.launch {..}
, nothing will change, everything is exactly the same, since before and after, the coroutine block will run on main thread consistently.
But, what if we change the L68 like:
coroutineScope.launch(Dispatchers.IO) { .. }
Well, this time, the app will crash because of it's trying to update the UI from a worker thread:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-4
Process: com.raywenderlich.snowy, PID: 8562
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
This is because, the L68's Dispatchers.IO overrode the L63's Main.
Just keep the question and my post for a while here, in case it could help someone like me had the same confuse.
Upvotes: 2