Anko的uiThread偶尔没有被解雇

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

// 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)上被触发。 虽然我的数据没有任何错误或exception被解析, uiThread括号中的代码片段将不会被执行。

到目前为止,我无法确定这种行为的任何理由。 没有logcat日志,什么都没有。 这个错误将不会出现。

有没有人与kotlin和/或Anko有相同或相似的问题?

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

我有同样的问题,这是因为一个未捕获的exception发生在后台。

用try / catch来围绕你的后台任务,你应该能够看到发生了什么。

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

谢谢你的帮助。 我已经知道了自己,所以我张贴这个答案,以防万一谁面临这个问题。

TL; DR: 上下文丢失,所以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的行动,这可能会或可能不会获得释放的上下文

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

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

据我现在可以告诉,这似乎已经做了伎俩。