首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将协程作用于片段,以便在片段不在屏幕上或被销毁时自动取消?

如何将协程作用于片段,以便在片段不在屏幕上或被销毁时自动取消?
EN

Stack Overflow用户
提问于 2020-03-17 02:51:23
回答 1查看 2.5K关注 0票数 1

我有这个片段,在检索数据时,它只是一个闪屏。问题是,在配置更改时,或者如果片段在屏幕外(用户导航到应用程序之外),当它从IO协程块返回并尝试在主协程块中执行导航时,它会崩溃。

代码如下:

注意:如果数据不存在或陈旧,viewModel.repository.initData()会调用Retrofit并将响应持久化到Room数据库。

代码语言:javascript
运行
复制
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线程和导航上的主线程。

我一直在阅读有关协程作用域的文章,但我仍然感到困惑/不确定它是如何工作的,以及如何正确地设置它。

EN

回答 1

Stack Overflow用户

发布于 2020-03-17 06:58:21

我可以通过实现如下代码来修复它:

代码语言:javascript
运行
复制
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)
                }
            }
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60711661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档