Android Kotlin обрабатывает исключения в потоке пользовательского интерфейса с помощью anko doAsync

Я новичок в Kotlin, и у меня есть doAsync с собственным обработчиком исключений:

doAsync(exceptionHander = {e -> handleException(e)}){
     //rest call
}

 private val handleException= {throwable : Throwable ->
        if(throwable is HttpClientErrorException){
            val response = JSONObject(throwable.responseBodyAsString)
            Toast.makeText(this, response["message"].toString(), Toast.LENGTH_LONG).show()
        }
    }

Однако тост никогда не отображается. Как я могу показать это сообщение об исключении в тосте? Вызывается ли обработчик исключений в потоке пользовательского интерфейса?

Обновление:

Я тестировал следующим образом:

doAsync(exceptionHander = {e -> handleException(e)}){
      throw HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "An error has occurred")
}

с тем же обработчиком ошибок, однако всплывающее уведомление не отображается.


person rena    schedule 05.03.2018    source источник
comment
Может быть, это глупый вопрос, но вы уверены, что ваше исключение — это HttpClientErrorException?   -  person user2340612    schedule 06.03.2018
comment
Да, даже если тост не будет отображаться.   -  person rena    schedule 06.03.2018
comment
Получаете ли вы какие-либо исключения в LogCat? Где запускается исключенияHandler, в основном потоке или в фоновом потоке?   -  person user2340612    schedule 10.03.2018
comment
Да, у меня есть исключение в LogCat. Я не уверен, работает ли обработчик исключений в основном или фоновом потоке. Это было частью вопроса ????   -  person rena    schedule 10.03.2018
comment
Если у вас есть исключение в LogCat, всегда полезно опубликовать его вместе с кодом, чтобы получить более быстрый и точный ответ. Не могли бы вы вставить его, если у вас все еще есть проблема?   -  person user2340612    schedule 10.03.2018
comment
У меня нет с собой ноутбука, я обновлю вопрос, как только смогу.   -  person rena    schedule 10.03.2018


Ответы (2)


Поскольку обработчик исключений вызывается в фоновом потоке, я использовал try-catch в блоке doAsync.

doAsync{
     var exception: Exception? = null
     try {
          //rest call
     }
     catch(e: HttpClientErrorException){
          exception = e
     }
     uiThread {
        if (exception != null){
             // Show the exception message. 
        }
        else {
             // Update the UI with the result
        }
     }
}

Таким образом, можно обработать ожидаемое исключение в потоке пользовательского интерфейса. Обратная связь приветствуется.

person rena    schedule 27.03.2018

Я также думаю, что неожиданные исключения НЕ следует игнорировать (или просто регистрировать). Но не очень удобно каждый раз добавлять блок try-canth при использовании doAsync. Я создал следующую служебную функцию:

fun <T> T.doAsyncThrowOnUI(task: AnkoAsyncContext<T>.() -> Unit) = doAsync(
        exceptionHandler = { thr -> Handler(Looper.getMainLooper()).post { throw thr }},
        task = task)

Он просто вызывает doSync Анко и передает обработчик исключений, который повторно генерирует все необработанные исключения в потоке пользовательского интерфейса. Используйте doAsyncThrowOnUI вместо doAsync Анко.

doAsyncThrowOnUI {
     // do something on bg thread (exceptions rethrown on ui thread)

     uiThread {
        // do something on ui thread
     }
}
person jackes    schedule 28.11.2018