我目前正在使用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括号中的代码段。

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

是否有人对Kotlin和/或Anko有相同或相似的问题?

更新:我已经找到了解决方案,请查看下面的答案以获取解释。

最佳答案

谢谢您的帮助。
我已经自己弄清楚了,所以我发布此答案以防万一其他人遇到这个问题。

TL; DR:上下文丢失,因此不会执行uiThread

解:
我偶然发现了post,其中提到了uiThread方法的一个重要功能:



经过进一步调查,我在解析完成后立即发现了以下日志,并且应该在其中调用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 Action ,可能会或可能不会释放上下文。

为了防止这种情况,我使用了Ankos runOnUiThread ,可以在给定的上下文引用上调用它:
// Asynchronously parse server response
doAsync {
    val itemlist = parseResponse(response)
    context.runOnUiThread {
        Otto.INSTANCE.post(UpdateRedeemedVoucherViewsEvent(itemlist))
    }
}

据我目前所知,这似乎已经解决了问题。

关于android - Anko的uiThread偶尔不被触发,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46795795/

10-12 03:20