Why Using GlobalScope Is Discouraged In Kotlin-Coroutines?
This Is Why You Shouldn't Use GlobalScope every time!
Why Using GlobalScope Is Discouraged?
- When We Use
GlobalScope
To Launch A Coroutine It Will be Launched In Top-Level Coroutine As It's Global And It Will Be Remained Until Your Application Is Dead.
In Other Words:
If You Are Using
GlobalScope
To Launch A Coroutine It Will Be Alive Until Your Application Is Dead Even You Have Skipped The Particular Activity || Fragment Where That Particular Corotuine Has Been Launched.As You Already Know That Coroutines Are Light-Weight But Still It
Will Consume Some Memory Resources
While It's Running For Sure, Which May Cause Memory Leaks In Your Application.
Solution
- You Can Use Pre-Defined Scopes Such As
lifecycleScope{...}
And If You Are Working With ViewModel(s) You Can UseviewModelScope{...}
To Launch A Coroutine And Get Started.
Practical Difference
Let's Test With Both GlobalScope{...}
And lifecycleScope{...}
For Better Understanding
- I Have Created Two Fragments And Added Navigation Between Both Fragments Through Navigation Component.
First Fragment's XML:
Second Fragment's XML:
Time For The Truth🔥
Before Moving To Further Make Sure
That You Have Included Coroutines Dependency If It's Not Included:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
In First Fragment's Kotlin File:
With GlobalScope{...}
Primarily Coroutine Will Be Launched Asusal With
GlobalScope{...}
When Button Is Pressed.When Button Will Be Pressed An Infinite Loop Will Run With A Second Delay every time.
After 5 Seconds Delay, Second Fragment Will Be Launched As You Can See Below In The Code:
view.toSecondFragment.setOnClickListener {
GlobalScope.launch{
while (true) {
delay(1000L)
Log.d("From GlobalScope", "Global Scope Is Still Running")
}
}
GlobalScope.launch(Dispatchers.Main){
delay(5000L)
Navigation.findNavController(view).navigate(R.id.firstFragment_to_secondFragment)
}
}
- Now Launch The Application After A Successful Build:
As You Can See That Even Though First Fragment Has Dead Our Loop Still Continues As We Declared Our Scope As
GlobalScope{...}
Which Will Continues To Run Until Our Application Is Dead.This Is The Main Reason Why Using GlobalScope Is Discouraged In Kotlin-Coroutines.
With lifecycleScope{...}
Primarily Coroutine Will Be Launched Asusal With
lifecycleScope{...}
When Button Is Pressed.When Button Will Be Pressed An Infinite Loop Will Run With A Second Delay every time.
After 5 Seconds Delay, Second Fragment Will Be Launched.
As You Can See In The Code That I Have Mentioned viewLifecycleOwner
Before Launching The Coroutine With lifecycleScope{...}
It's Because I am Working With Fragments.
viewLifecycleOwner
Is Added When The Fragment Has Its UI ( onCreateView() , onDestroyView() ) This Is Added To The Fragment's Overall Lifecycle ( onCreate() , onDestroy() ).In case, If You Are Working With Activities You Don't Need To Mention
viewLifecycleOwner
.
view.toSecondFragment.setOnClickListener {
viewLifecycleOwner.lifecycleScope.launch{
while (true) {
delay(1000L)
Log.d("From LifeCycleScope", "LifeCycleScope Is Still Running")
}
}
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main){
delay(5000L)
Navigation.findNavController(view).navigate(R.id.firstFragment_to_secondFragment)
}
}
- Now Launch The Application After A Successful Build:
- As You Can See That Once The Fragment Has Dead Coroutine Execution Has Stopped.
Same Implies To viewModelScope{...}
As Well, It Will Also Perform Same As lifecycleScope{...}
. But You'll Be Using viewModelScope{...}
When you Are Working With ViewModel(s).
Conclusion
Use
GlobalScope{...}
When You Want An Operation To Run Until The Application Is Dead If Not You Should Definitely UselifecycleScope{...}
.If You Are Working With ViewModel(s) You Can Use
viewModelScope{...}
.
Well, That's All For Now🙌
Bye🤗