【问题标题】:Android Coroutine doesn't finishAndroid协程没有完成
【发布时间】:2019-09-28 04:45:39
【问题描述】:

我有一个代码,我使用 kotlin couroutines 懒惰地更新 UI。

当我将一些代码放入GlobalScope.async 时,只执行前几行,其余代码不执行


class MyFragment : Fragment(), CoroutineScope {

    private lateinit var masterJob: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + masterJob

   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
           GlobalScope.async(coroutineContext) {
            api.fetchOrders()
            configureOrders(view!!)

            // Some code here ... 
        }
   }

例如在上面的代码中,注释后面的代码没有被执行。如果我将注释上面的代码与上面的代码交换,那么它就不会被执行。

我错过了什么?

【问题讨论】:

  • 您没有等待从async 返回的Deffered。我不确定,但它可能会在onViewCreated 结束后被取消。另外,您检查过未处理的异常吗?

标签: kotlin kotlin-coroutines


【解决方案1】:

当你有一个返回一些东西的异步方法时,它是异步的,问题是只有方法的第一行被执行,因为你没有用关键字 await 等待方法完成。

某事需要函数返回的值并强制函数结束,除非你使用await,否则它必须等待函数结束。

【讨论】:

    【解决方案2】:

    代码不正确,因为您的协程上下文正在主线程上运行,在协程上下文初始化时使用 Dispatchers.Main 关键字。如果您想执行 API 调用,请更改为Dispatchers.IO。

    我假设api.fetchOrders() 不能在主线程上运行。另外,您需要使用关键字 .await() 等待该响应:

    val yourData = api.fetchOrders().await() 将返回您的 Deferred 类型中的内容。例如,如果它是 Deferred<ArrayList>,它会在您调用 await() 方法后返回 ArrayList。

    注意。

    如果您在该协程上下文中调用 await(),我相信您应该遇到类似 NetworkOnMainThreadException 的错误

    【讨论】:

      【解决方案3】:

      我发现了问题所在,代码正在运行,但它导致了堆栈跟踪中不可见的异常(不知道为什么)。

      当我将 GlobalScope.async 更改为 GlobalScope.launch 时,它开始工作

      【讨论】:

        【解决方案4】:

        有几点:

        1. 您的片段是一个范围,但您仍然使用 GlobalScope。 Dispatchers.Main + masterJob 被完全忽略
        2. 如果您使用 fragmentScope,根据 api.fetchOrders 的实现,您的应用可能会崩溃,因为您仍在主线程中
        3. 看来您对结果不感兴趣,所以不要使用Deferred
        4. 如果async是你想要的,你必须打电话给await

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-29
          • 2017-12-17
          相关资源
          最近更新 更多