【问题标题】:Crash in coroutine协程崩溃
【发布时间】:2020-07-22 03:00:10
【问题描述】:

我的功能很简单,

主线程:初始化一个变量 ->

后台线程:触发网络请求,将结果赋回上一个变量->

主线程:显示该变量

代码如下:

suspend fun createCity(context: Context, newCity: MutableLiveData<NewIdea>, mapBody: Map<String, String>, token: String) {
    lateinit var response: NewIdea
    try {
        withContext(Dispatchers.IO) {
            val map = generateRequestBody(mapBody)
            response = webservice.createIdea(tripId, map, "Bearer $token")
            getTrip(context, token)
        }
    } catch (e: Exception) {
        Log.e(TAG, e.message)
    }
    newCity.value = response
}

但有时(实际上只发生了 2 次)crashlytics 报告此行崩溃 newCity.value = response

Fatal Exception: kotlin.UninitializedPropertyAccessException: lateinit property response has not been initialized

我真的不明白这是怎么发生的。 这是从协程函数返回值的正确方法吗?

谢谢

【问题讨论】:

标签: kotlin coroutine


【解决方案1】:

如果 try 块失败,可能会发生 lateinit 变量根本没有设置。您也应该将 ui 更新代码放在 try 块中,并单独处理 Exception

旁注:withContext 已针对返回值进行了很好的优化,因此您可以使用它。

suspend fun createCity(context: Context, newCity: MutableLiveData<NewIdea>, mapBody: Map<String, String>, token: String) {
    try {
        val response: NewIdea = withContext(Dispatchers.IO) {
            val map = generateRequestBody(mapBody)
           // does createIdea() first store it in var, then does getTrip(), then returns the result of createIdea() stored previously
            webservice.createIdea(tripId, map, "Bearer $token").also { getTrip(context, token) }  // ^withContext
        }
        newCity.value = response
    } catch (e: Exception) {
        Log.e(TAG, e.message)
    }
}

快速提示(可选):您可以使用 withContext 包装 UI 更新代码,当不在主线程中运行时将工作分派到 Dispatchers.Main,而如果在 main 中运行什么都不做:

withContext(Dispatchers.Main.immediate) {
    val response: NewIdea = withContext(Dispatchers.IO) {
        val map = generateRequestBody(mapBody)
        // does createIdea() first store it in var, then does getTrip(), then returns the result of createIdea() stored previously
        webservice.createIdea(tripId, map, "Bearer $token").also { getTrip(context, token) }  // ^withContext
    }
    newCity.value = response
}

【讨论】:

    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多