简体   繁体   English

退出活动时协程作业是否自动取消?

[英]Is Coroutine job auto cancelled upon exiting Activity?

I have the below code of a slow loading image我有以下慢速加载图像的代码

class MainActivity : AppCompatActivity() {
    private lateinit var job: Job

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val imageLoader = ImageLoader.Builder(this)
            .componentRegistry { add(SvgDecoder(this@MainActivity)) }
            .build()

        job = MainScope().launch {
            try {
                val request = ImageRequest.Builder(this@MainActivity)
                    .data("https://restcountries.eu/data/afg.svg")
                    .build()
                val drawable = imageLoader.execute(request).drawable
                Log.d("TrackLog", "Loaded")
                findViewById<ImageView>(R.id.my_view).setImageDrawable(drawable)
            } catch (e: CancellationException) {
                Log.d("TrackLog", "Cancelled job")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
//        job.cancel()
    }
}

If I exit the activity before the image loaded completed, I thought I should manually perform job.cancel() to get the coroutine canceled.如果我在图像加载完成之前退出活动,我认为我应该手动执行job.cancel()以取消协程。

However, even when I commented out the job.cancel() , the job still get canceled when I exit MainActivity .但是,即使我注释掉了job.cancel() ,当我退出MainActivity时,作业仍然会被取消。

This is also true when I use either GlobalScope or even use a global variable scope and job.当我使用GlobalScope甚至使用全局变量 scope 和作业时也是如此。

val myScope = CoroutineScope(Dispatchers.IO)
private lateinit var job: Job

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val imageLoader = ImageLoader.Builder(this)
            .componentRegistry { add(SvgDecoder(this@MainActivity)) }
            .build()

        job = myScope.launch {
            try {
                val request = ImageRequest.Builder(this@MainActivity)
                    .data("https://restcountries.eu/data/afg.svg")
                    .build()
                val drawable = imageLoader.execute(request).drawable
                Log.d("TrackLog", "Loaded")
                findViewById<ImageView>(R.id.my_view).setImageDrawable(drawable)
            } catch (e: CancellationException) {
                Log.d("TrackLog", "Cancelled job")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
//        job.cancel()
    }
}

I'm puzzled how did the job get canceled when we exit the Activity even when I don't call job.cancel() .我很困惑,即使我没有调用job.cancel() ,当我们退出 Activity 时,作业是如何被取消的。

Apparently, because my request is made of this@MainActivity显然,因为我的request是由this@MainActivity

                val request = ImageRequest.Builder(this@MainActivity)
                    .data("https://restcountries.eu/data/afg.svg")
                    .build()

hence, when exiting, the this@MainActivity is killed, hence the request also got terminated and perhaps canceled?因此,退出时, this@MainActivity被杀死,因此request也被终止并可能被取消?

If we use baseContext如果我们使用baseContext

                val request = ImageRequest.Builder(baseContext)
                    .data("https://restcountries.eu/data/afg.svg")
                    .build()

then we have to manually cancel the job during onDestroy然后我们必须在onDestroy期间手动取消作业

Therefore it is always safer to use lifecycleScope因此,使用lifecycleScope范围总是更安全

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM