Reputation: 60081
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.
However, even when I commented out the job.cancel()
, the job still get canceled when I exit MainActivity
.
This is also true when I use either GlobalScope
or even use a global variable scope and job.
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()
.
Upvotes: 1
Views: 437
Reputation: 60081
Apparently, because my request
is made of 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?
If we use baseContext
val request = ImageRequest.Builder(baseContext)
.data("https://restcountries.eu/data/afg.svg")
.build()
then we have to manually cancel the job during onDestroy
Therefore it is always safer to use lifecycleScope
Upvotes: 2