在 Android 应用程序中,有一个用于RecyclerView
显示元素的片段。
最初,元素没有数据,但是当您单击它们时,将为每个元素启动一个单独的函数loadElementData
,将数据加载到元素中。
每个元素在加载时都会显示一个旋转的图标ProgressBar
。
加载数据没有问题,一切正常。
问题恰恰出在加载指示的显示上,或者更准确地说,问题出在其中一种情况下指示器不会消失的事实。
由于fragment工作在用户可以退出fragment并且下载不会被取消的viewModel
级别,因此有4种可能的情况:Activity
用户点击元素,指示器显示,数据加载,指示器消失。-作品
用户点击元素,显示指示器,用户重新输入相同的片段,但使用不同的元素集,加载被取消,进入带有加载元素的片段后,它们不再加载,指示器被隐藏。-作品
用户点击元素,指示器显示,用户离开片段,数据加载,用户返回片段,数据加载,指示器隐藏。-作品
用户点击元素,指示器被显示,用户退出片段并立即返回,数据正在加载,指示器被显示,数据已经加载,指示器仍然显示。
问题出在场景 4 上。由于某种原因,在这种情况下,加载指示器不会消失。可能是什么原因造成的?我该如何解决这个问题?
代码:
private fun loadItemData(item: MyItem) {
val index = viewModel.currentList.value!!.indexOf(item)
item.isDataLoading = true
itemAdapter.notifyItemChanged(index)
val job = requireActivity().lifecycleScope.launchPausing(Dispatchers.IO) {
var itemData: ItemData? = null
try {
itemData = async { getItemData(item.id) }.await()
itemData?.let { item.data = it }
} catch (e: CancellationException){
Log.d("debug", "loading canceled")
} finally {
item.isDataLoading = false
activity?.runOnUiThread {
itemAdapter.notifyItemChanged(index)
}
}
}
viewModel.loadItemDataJobs.add(job)
requireActivity().lifecycleScope.launch(Dispatchers.IO) {
job.join()
if (job in viewModel.loadItemDataJobs)
viewModel.loadItemDataJobs.remove(job)
}
}
使用该库,pausing-coroutine-dispatcher
我可以暂停和恢复 和 中的协onPause
程onResume
。此类协程是使用启动的launchPausing
implementation 'com.github.Koitharu:pausing-coroutine-dispatcher:1.0'