android - 退出活动时协程作业是否自动取消?
问题描述
我有以下慢速加载图像的代码
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()
}
}
如果我在图像加载完成之前退出活动,我认为我应该手动执行job.cancel()
以取消协程。
但是,即使我注释掉了job.cancel()
,当我退出时,作业仍然会被取消MainActivity
。
当我使用GlobalScope
或什至使用全局变量范围和作业时也是如此。
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()
}
}
我很困惑当我们退出 Activity 时,即使我没有调用,作业是如何被取消的job.cancel()
。
解决方案
显然,因为 myrequest
是由this@MainActivity
val request = ImageRequest.Builder(this@MainActivity)
.data("https://restcountries.eu/data/afg.svg")
.build()
因此,退出时,this@MainActivity
被杀死,因此request
也被终止并可能被取消?
如果我们使用baseContext
val request = ImageRequest.Builder(baseContext)
.data("https://restcountries.eu/data/afg.svg")
.build()
然后我们必须在期间手动取消作业onDestroy
因此使用起来总是更安全lifecycleScope
推荐阅读
- javascript - 在 Google 表格中使用脚本设置公式
- flutter - AndroidAlarmManager 无效日期颤振
- r - 当术语不准确时,有没有办法通过将术语从一列匹配到另一列来填充空白列?
- xcode - Xcode:如何方便地使用库/框架,同时保持代码对他人的私密性?
- python - 如何遍历未使用 XlsxWriter 明确命名的 Excel 工作表?
- javascript - 如何在 JavaScript 的循环中运行异步 $.getJSON 函数?
- mongodb - 查询数组并忽略元素的顺序
- reactjs - Ionic/React - 浏览器自动填充输入项时如何从输入项中获取值?
- excel - 如何过滤然后填充到单独的工作表上?
- powershell - 从 html 元素中提取 http 链接