1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Using a coroutine without a "GlobalScope" in Activity and Fragment

Last updated at Posted at 2020-09-30

ActivityとFragmentでGlobalScopeを使わないでコルーチンを利用する方法です。
GlobalScopeを何気なく使わないようにしましょう。

Do not use GlobalScope in local scope

At First. Look at follow code.
This example code is wrong coroutine usage.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        GlobalScope.launch { 
            val data = withContext(Dispatchers.IO) {
                loadData()
            }
            initUi(data)
        }
    }
    ...
}

This is a bad way.
But Why?
According to Officially GlobalScope explains at "GlobalScope - kotlinx-coroutines-core", GlobalScope's lifecycle scope is Process-Level. So, this loading data may keep running after Activity(also Fragment) Destroyed, and then happen unexpected behavior.

How to use Coroutines on Activity and Fragment without GlobalScope : Use LifecycleScope

Use androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01 or higher.
So you can write like this example.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        lifecycleScope.launch { 
            val data = withContext(Dispatchers.IO) {
                loadData()
            }
            initUi(data)
        }
    }
    ...
}

In Fragment, use viewLifecycleOwner.

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch { 
            val data = withContext(Dispatchers.IO) {
                loadData()
            }
            initUi(data)
        }
    }
    ...
}

Because LifecycleScope is lifecycle-aware, so if you want to use asynchronous tasks with only Activity and Fragment lifecycle scopes, it makes more sense to use LifecycleScope than GlobalScope.

See more: https://developer.android.com/topic/libraries/architecture/coroutines

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?