首页 > 解决方案 > 协程崩溃

问题描述

我的功能很简单,

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

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

主线程:显示该变量

下面的代码:

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

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

谢谢

标签: kotlincoroutine

解决方案


好吧,如果 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
}

推荐阅读