#android #kotlin #retrofit2 #kotlin-coroutines
Вопрос:
У меня есть вариант использования всякий раз, когда в вызове API возникает общая ошибка, такая как потеря Интернета или неизвестная ошибка, необходимо отобразить пользовательский интерфейс ошибки с кнопкой повтора. когда пользователь нажимает кнопку повторить ранее неудачную попытку, API должен вызвать и возобновить поток пользователей.
Интерфейс API перед переносом метода сопрограмм:
interface TodoService {
@POST("todo/create")
fun createTodo(@Body request: TodoRequest): Call<TodoResponse>
}
Клиент API:
fun <T> fetch(call: Call<T>, completion: (result: NetworkBoundResource<T>) -> Unit) {
call.enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
// I have the mechanism save call object and completion and show error UI
// when user press retry fetch(call.clone(), completion
}
override fun onResponse(call: Call<T>, response: Response<T>) {
}
})
}
Это не было проблемой до переноса интерфейса дооснащения на методы приостановки сопрограмм. Потому что я могу просто клонировать объект вызова модернизации (call.clone())
и повторить вызов API, как описано в комментариях к коду.
Интерфейс API после переноса метода сопрограмм:
interface TodoService {
@POST("todo/create")
suspend fun createTodo(@Body request: TodoRequest): TodoResponse
}
Теперь, как я могу получить ту же функцию без объекта вызова?
Ответ №1:
Вы можете выполнить повторную попытку, сохранив действие за пределами задания сопрограммы, например, добавив отправку на кнопку.
Вот простой пример, но не завершенный:
class ViewModel {
val context = CoroutineScope(Dispatchers.Main)
var dispatchRetry: (() -> Unit)? = null
fun createTodo(requestData: TodoRequest) {
context.launch() {
try {
todoService.createTodo(requestData)
} catch (t: Throwable) {
dispatchRetry = { todoService.createTodo(requestData) }
}
}
}
fun retry() {
dispatchRetry?.invoke()
}
}
Комментарии:
1. это решение полезно. но мне приходится справляться с каждой моделью представления. таким образом, решение не является масштабируемым.
2. Если у вас есть только несколько запросов, я бы выбрал не обобщенное решение (следуйте за ПОЦЕЛУЕМ). Но вы также можете создать свою собственную оболочку, которая обрабатывает каждое выполнение сопрограммы с помощью повторной попытки.
Ответ №2:
используйте репозитории и модель просмотра, чтобы получать ответы через текущие данные с помощью сопрограмм, а затем в вашей активности наблюдатели за пользователями, чтобы узнать дату. это лучший способ использовать сопрограммы, а также лучшая практика для MVVM
Комментарии:
1. Я следую шаблону репозитория. Похоже, ты не понял моего вопроса. Я не использую вызов дооснащения<T>, потому что в этом нет необходимости, если вы приостанавливаете. теперь, как вы повторите попытку ?