Android Kotlin Совместные исключения - PullRequest
1 голос
/ 20 апреля 2020

Я пытаюсь использовать Kotlin сопрограмм для запуска сетевого запроса и обработки исключений. Я посмотрел много уроков по сопрограммам, но я действительно изо всех сил пытаюсь связать то, что я знаю, с проблемой, которая у меня есть.

Проблема

Попытка получить исключение для быть пойманным в представлении, но из ViewModel не выдается исключение, поэтому приложение вылетает.

Приложение Code

My Android имеет три уровня, которые относятся к этой проблеме. У меня есть View, ViewModel и слой службы. На уровне службы request.execute () может выдать исключение UserAuthException.

MyView (View)

private val mViewModel: MyViewModel by viewModels()

private fun getFileId() {
    try {
        mViewModel.requestFileId()
    } catch (e: UserAuthException) {
        Timber.i(e)
    }
}

MyViewModel (ViewModel)

private val apiService = MyApiService()

fun requestFileId() {
    viewModelScope.launch {
        ApiService.requestFileId()
    }
}

MyApiService (Сервисный уровень)

suspend fun requestFileId(): FileId = withContext(Dispatchers.IO) {
    request.execute()
}

Вещи, на которые я смотрел

Я играл с CoroutineExceptionHandlers, supervisorJobs с не повезло, но без фундаментальных знаний о том, как все это работает, я не добьюсь никакого прогресса.

Любая помощь будет оценена, спасибо.

Ответы [ 2 ]

1 голос
/ 21 апреля 2020
fun requestFileId() {
    viewModelScope.launch {
        ApiService.requestFileId()
    }
}

Это не приостанавливаемая функция. Он запускает параллельную сопрограмму и сразу же возвращается. Ясно, что вызов requestFileId() никогда не вызовет исключение.

Запуск сопрограммы аналогичен запуску другого потока, он вводит параллельность в ваш код. Если ваш текущий код надеется остаться непараллельным при наблюдении результатов приостановленных функций, возможно, вы обращаете внимание на значительные архитектурные изменения в приложении, чтобы оно работало правильно при одновременном выполнении.

0 голосов
/ 20 апреля 2020

В вашей модели измените его на что-то вроде этого:

fun requestFileId() {
  viewModelScope.launch {
    try {
      ApiService.requestFileId()
    } catch (e: Exception) {
      // inform your view
    }
  }
}
...