【问题标题】:Anko's uiThread sporadically not firedAnko 的 uiThread 偶尔没有被解雇
【发布时间】:2017-10-17 17:23:48
【问题描述】:

我目前正在使用 Anko 的 doAsync 来处理异步任务。 具体来说,我使用它来解析响应 json 到数据对象的 ArrayList,如下所示:

// Asynchronously parse server response
doAsync {
    val itemlist = parseResponse(response)
    uiThread {
        Otto.INSTANCE.post(UpdateRedeemedVoucherViewsEvent(itemlist))
    }
}

在大多数情况下,例如在 Google Pixel (Android 8.0.0) 上,这都能正常工作。我的对象被解析,Otto 总线事件 将被发布到 ui 线程

但在极少数情况下,此过程会失败。 到目前为止,我注意到 ui 线程调用不会在 Galaxy S5 Mini (Android 5.1.1) 上触发。虽然我的数据被解析没有任何错误或异常,但 uiThread 括号中的代码 sn-p 不会被执行。

到目前为止,我无法确定这种行为的任何原因。没有 logcat 日志,什么都没有。没有计划何时出现此错误。

有人对 kotlin 和/或 Anko 有相同或类似的问题吗?

更新:我自己找到了解决方案,请参阅下面的答案以获得解释。

【问题讨论】:

  • 你能发布你的parseResponse代码吗?

标签: android asynchronous kotlin anko


【解决方案1】:

感谢你们的帮助。 我自己想通了,所以我发布这个答案以防万一其他人遇到这个问题。

TL;DR:context 丢失了,所以 uiThread 不会被执行

解决方案: 我偶然发现了这个post,其中提到了 uiThread 方法的一个重要特性:

基本上你有一个异步函数,它将在另一个线程中执行它的代码,并提供使用 uiThread 返回主线程的机会。 async 是为 Context 实现的扩展函数,会使用它的弱引用,所以不会阻止 GC 释放它的内存。

经过进一步调查,我在解析完成后发现了以下日志,并且应该在哪里调用 uiThread

I/art: Background partial concurrent mark sweep GC freed 30879(16MB) AllocSpace objects, 16(2MB) LOS objects, 40% free, 16MB/27MB, paused 2.123ms total 196.372ms

看来确实有一些 GC 动作,可能会也可能不会释放 context

为了防止这种情况,我正在使用 Ankos runOnUiThread,它可以在给定的上下文引用上调用

// Asynchronously parse server response
doAsync {
    val itemlist = parseResponse(response)
    context.runOnUiThread {
        Otto.INSTANCE.post(UpdateRedeemedVoucherViewsEvent(itemlist))
    }
}

据我目前所知,这似乎已经成功了。

【讨论】:

  • 这样做,您正在泄漏您的上下文实例。我不确定它是否会在此之后释放,因为生命周期无法正确销毁它,你知道吗?
  • 是的,我知道这一点。但目前,这是我可以始终如一地调用它的唯一方法。我会密切关注这一点,如果它引起任何进一步的问题,我会报告
【解决方案2】:

我遇到了同样的问题,这是因为后台发生了未捕获的异常。

用 try/catch 包围你的后台任务,你应该能够看到正在发生的事情。

doAsync {
    try {
        val itemlist = parseResponse(response)
    } catch(t: Throwable) {
        //TODO log your exception
    ]
    uiThread {
        Otto.INSTANCE.post(UpdateRedeemedVoucherViewsEvent(itemlist))
    }
}

【讨论】:

  • 不幸的是,这不起作用。 catch case 和 uiThread 都不会被输入
猜你喜欢
  • 1970-01-01
  • 2020-03-28
  • 2015-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-16
相关资源
最近更新 更多