如何将Coroutine的范围扩大到Fragment,以便在Fragment离开屏幕或被销毁时自动取消



我有这个片段,它只是检索数据时的启动屏幕。问题是,在配置更改时,或者如果Fragment在屏幕外(用户从应用程序中导航出来(,当它从IO Coroutine块返回并试图执行Main Coroutine框中的导航时,它会崩溃。

这是代码:

注意:如果数据不存在或过时,viewModel.repository.initData()会发出"改装"调用,并持续对Room数据库的响应。

class LoadingFragment : Fragment() {
private lateinit var viewModel: LoadingViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_loading, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(LoadingViewModel::class.java)
CoroutineScope(Dispatchers.IO).launch {
// Small delay so the user can actually see the splash screen
// for a moment as feedback of an attempt to retrieve data.
delay(250)
try {
viewModel.repository.initData()
CoroutineScope(Dispatchers.Main).launch {
findNavController().navigate(R.id.action_loadingFragment_to_mainFragment)
}
} catch (e: IOException) {
findNavController().navigate(R.id.action_loadingFragment_to_errorFragment)
}
}
}
}

此外,我需要导航只在检索数据后进行,但数据检索必须在IO线程上进行,导航必须在主线程上进行。

我一直在读关于确定Coroutine范围的文章,但我仍然很困惑/不确定它是如何工作的,以及如何正确设置它。

我能够通过实现这样的东西来修复它:

class LoadingFragment : Fragment() {
private lateinit var viewModel: LoadingViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_loading, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(LoadingViewModel::class.java)
lifecycleScope.launch {
withContext(Dispatchers.IO) {
// Small delay so the user can actually see the splash screen
// for a moment as feedback of an attempt to retrieve data.
delay(250)
try {
viewModel.initData()
withContext(Dispatchers.Main) {
findNavController().navigate(R.id.action_loadingFragment_to_mainFragment)
}
} catch (e: IOException) {
findNavController().navigate(R.id.action_loadingFragment_to_errorFragment)
}
}
}
}
}

相关内容

最新更新