Before Getting Started I Suggest You Understand What's Actually A Coroutine Contexts Is, Which I Have Discussed In The Previous Blog In This Series. And Make Sure
That You Have Included Coroutines Dependency If It's Not Included:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
-> You May Know That delay()
Is A Suspend Function That delays a coroutine for a specific time. But It Won't Block
Whole Thread.
-> However, We Have Something Know As runBlocking
In Coroutines Which Will Start A New Coroutine When You Assign It, Which Starts In Main Thread By Default.
-Before Going To Further, I Want To Clear That runBlocking
Will Block Whole Thread But GlobalScope.launch(...){ }
Won't.
Confusing🤔? Not A Problem🙌,
Here Are Two Examples Which May Clear That Confusion:
1.
If If Implement delay()
In GlobalScope.launch(...){...}
, I Can Still Able To Operate UI From My Coroutine Even runBlocking()
Is Executed:
Logcat Info:
Launched Activity Info+Activity:
->And As You Can See In Both Logcat And In Mobile, It's Working Like Charm Even runBlocking()
Is Executed, It's Because I Haven't Implemented Anything In runBlocking()
.
2.
In This Example I'll Implement delay()
In runBlocking()
, So That You'll Get An Idea About runBlocking()
And What's The Actual Use In Real.
Logcat Info:
Launched Activity Info+Activity:
->And As You Can See In Both Logcat And In Mobile, Main Thread Has Been Blocked Including GlobalScope.launch(...){...}
(As It's Dealing With Main Thread Too) For A Certain Time And When That Time Has Completed runBlocking()
Immediately Releases The Block After It's Execution And Back To Normal State.
I Hope Your Confusing Regarding
runBlocking()
Has Cleared.
->We'll That's It About runBlocking()
, But Why Would Someone Block UI Updates Or Other Stuff In The Application🤔?
-It Can Be Useful If You Don't Necessarily Need Any Particular Coroutine Behaviour But Still Want To Call A Suspend Function In Your Main Thread.
-Another Use Case Scenario Is When You Are Testing With j-unit To Actually Access Suspend Function Within In A Test Function.
-And My Personal Experience With runBlocking()
Is That You Can Actually Play Around With Coroutines And runBlocking() To Check What's Actually Going On In Coroutines. In Other Words To Check Behind-The-Scenes Of Coroutines.
->And Yes, The Whole Code In runBlocking()
Will Be Synced With Our Normal MainThread Flow.
->As I Mentioned That runBlocking
Will Start A New Coroutine When You Assign It, That Mean We Can Launch Multiple Coroutines From The runBlocking
Too.
-Let's Check That:
->As You Can See That I Have Added The Code In Multiple Launches Which Will Change The logs In runBlocking() Itself And Once runBlocking() Execution Completes It Directly Jumps To Another CodeBlock, In Our Case, It Is GlobalScope.launch(...){...}
And App Will Notify Those Changes In Both Logcat And In Application:
GlobalScope.launch(Dispatchers.Main) {
Log.d("runBlocking", "Started Execution From GlobalScope")
delay(2000L)
textView.text = "In Global Scope"
}
runBlocking {
launch(Dispatchers.IO) {
Log.d("runBlocking", "Started Execution From runBlocking")
}
launch(Dispatchers.IO) {
Log.d("runBlocking", "Started Execution From Another runBlocking")
}
}
->And When You Are Trying To Implement Multiple Coroutine Launches From runBlocking(), It Will Execute All Those Launches Simultaneously At The Same Time As You Can See Timing In Logcat Too When Both Of The Logs From Two Launches Executed From runBlocking():
Well That's All For Now, In Upcoming Blog I'll Discuss Jobs In Coroutines😉
Bye🤗