【问题标题】:Error handling in Kotlin coroutines - How to display error on the UI?Kotlin 协程中的错误处理 - 如何在 UI 上显示错误?
【发布时间】:2022-01-01 16:54:31
【问题描述】:

显然我没能理解使用 kotlin 协程处理异常的逻辑。 请你帮助我好吗? 在我的 Android 应用上,我有一个按钮可以触发 fetch 功能。

这个函数做了三件事:

  1. 从服务器检索 json 文件 (getRequest) - 可能会失败

  2. 处理 json 文件 (processJSON) 并在 Departures (departures) 类的实例中临时存储 4 个值。 - 可能由于其他原因而失败

  3. 用这些值填充 4 个 TextView。 (ui更新) 我希望所有这些字段都填充一个由这些失败函数的 catch 子句生成的可理解的错误消息。 我怎样才能做到这一点?

     fun fetch(stopID: String, attr: String, value: String) {
             lifecycleScope.launch(Dispatchers.IO) {
                 try {
                     val result = getRequest(stopID)
                     val departures = processJSON(result, attr, value)
                     withContext(Dispatchers.Main) {uiUpdate(stopID, departures)}
                 } catch (e: Exception) {
                 }
             }
         }
    

如果我在这里删除 try-catch,应用程序会在出现异常时崩溃。 如果我将 uiUpdate 放入显示的 catch 子句中,它会再次崩溃。

【问题讨论】:

    标签: android kotlin kotlin-coroutines coroutine coroutinescope


    【解决方案1】:

    默认情况下lifecycleScope 使用Dispatchers.Main.immediate 调度程序。您可以删除 Dispatchers.IO 将其传递给 lifecycleScope.launch 并调用 suspend 函数,并将其包装到 try-catch 中:

     fun fetch(stopID: String, attr: String, value: String) = lifecycleScope.launch {
             try {
                 val result = getRequest(stopID)
                 val departures = processJSON(result, attr, value)
                 uiUpdate(stopID, departures)
             } catch (e: Exception) {
                 // You can update UI here as well
             }
     }
    

    【讨论】:

      【解决方案2】:

      谢谢谢尔盖!以下功能确实达到了我想要实现的目的。 我从函数内部删除了 try-catch,并在这些函数的声明之前添加了各自的 @Throws 表达式。

       fun fetch(stopID: String, attr: String, value: String) {
                lifecycleScope.launch(Dispatchers.Default) {
                    try {
                       val result = getRequest(stopID)
                       val departures = processJSON(result, attr, value)
                       withContext(Dispatchers.Main) {uiUpdate(stopID, departures)}
                   } catch (e: UnknownHostException) {
                        withContext(Dispatchers.Main) {uiUpdate(stopID, Departures("Error2","Error2"))}
                   } catch (e: JSONException) {
                        withContext(Dispatchers.Main) {uiUpdate(stopID, Departures("Error3","Error3"))}
                   } catch (e: Exception) {
                       withContext(Dispatchers.Main) {uiUpdate(stopID, Departures("Error4","Error4"))}
                   }
              }
          }
      

      【讨论】:

      • 如果您从launch 调用中删除调度程序,则可以删除所有withContext(Main)。它将默认使用。如果您确实需要 getRequest 和/或 processJSON 在其他调度程序上运行,您可以使用您想要的调度程序将 它们 包装在 withContext 中。请注意,withContext 返回 lambda 中最后一个表达式的值,因此您可以从中得到结果:val departures = withContext(Dispatchers.Default) { processJSON(...) }
      猜你喜欢
      • 1970-01-01
      • 2019-06-02
      • 2019-12-10
      • 2020-09-25
      • 2020-09-11
      • 2021-11-11
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多