Kotlin corountines:注意:结束时间超过纪元:

时间:2018-10-12 08:25:43

标签: android kotlin kotlinx.coroutines

合并runBlockingwithContext似乎在分发消息 Note: end time exceeds epoch:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        runBlocking {
            withContext(DefaultDispatcher) {
                null
            }
        }
    }
}

我使用了许多这样的协程,并且logcat被垃圾邮件了,有什么办法可以避免这种情况?另一种方法,例如:

var projects: List<ProjectEntity>? = runBlocking {
    withContext(DefaultDispatcher) {
        //Get the ProjectEntity list
    }
}
projects?.let {
    onResult(projects)
}

编辑

我尝试根据您的评论(谢谢),但无法获得与上述示例类似的结果:

Log.d("Coroutines", "getMostRecent start")
var localeProject: ProjectEntity? = null
launch {
    withContext(CommonPool) {
        Log.d("Coroutines", "getRecentLocaleProject")
        localeProject = getRecentLocaleProject()
    }
}
Log.d("Coroutines", "check localeProject")
if (localeProject != null) {
    //Show UI
}

在Logcat中:

D/Coroutines: getMostRecent start
D/Coroutines: check localeProject
D/Coroutines: getRecentLocaleProject

我想分离异步和同步内容,这是不可能的吗?我真的想尽可能避免存储库中的所有回调。

2 个答案:

答案 0 :(得分:1)

Markos注释正确,您不应阻止UI线程。

您应该使用launchasync并使用withContext切换回UI线程。

您可以在此处找到一些示例:https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md#structured-concurrency-lifecycle-and-coroutine-parent-child-hierarchy

class MainActivity : ScopedAppActivity() {

    fun asyncShowData() = launch { // Is invoked in UI context with Activity's job as a parent
       // actual implementation
    }

    suspend fun showIOData() {
        val deferred = async(Dispatchers.IO) {
        // impl      
        }
        withContext(Dispatchers.Main) {
          val data = deferred.await()
          // Show data in UI
        }
    }
}

请注意,该示例使用了新的协程API(> 0.26.0),该API重命名了Dispatchers。因此,Dispatchers.Main对应于旧版本中的UI

答案 1 :(得分:0)


let func = () => (<Image source={require('../images/image.png')} />)
<View>
  {func()}
  {func()}
  {func()}
  {func()}
  {func()}
</View>
  

我想分离异步和同步内容,没有这样的方法吗?

var localeProject: ProjectEntity? = null launch { withContext(CommonPool) { localeProject = getRecentLocaleProject() } } if (localeProject != null) { //Show UI } 协程在语义上就像是launch插入了一个线程。直觉告诉您,刚开始设置start的线程后就不能指望它,对于协程来说也是如此。它甚至更强大:保证不要看到localeProject != null,因为localeProject != null仅向事件循环添加了一个新事件。在您当前的方法完成之前,将不会处理该事件。

因此,您可以忘记从异步代码初始化的顶级launch。甚至val都无法使用,因为您无法保证会看到它已经初始化。您必须使用最宽松的类型:可为空的lateinit var s。