Kotlin, как можно повторить запрос, если возникает ошибка при нажатии на кнопку диалогового окна

Давайте представим ситуацию на Kotlin, когда мы пытаемся получить запрос, но не имеем подключения к Интернету и получаем ошибку, затем показываем AlertDialog, и нам нужно повторить запрос, если пользователь нажмет «положительную кнопку».

Этот метод проверяет существующего пользователя по номеру телефона:

override fun checkPhone(phone: String, context: Context) {
    view?.let {
        it.showOrHideProgressBar(true)
        apiManager.checkPhone(phone)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe({ result ->
                    view?.showOrHideProgressBar(false)
                    if (result.user_exists) {
                        view?.showLogin()
                    } else {
                        val code = result.confirmation_code
                        confirmPhone(phone, code, context)
                    }
                }, { error ->
                    handleAnyError(error, context)
                }).addToCompositeDisposable(compositeDisposable)
    }
}

И вот общий метод обработки ошибок:

private fun handleAnyError(it: Throwable, context: Context) {
    view?.showOrHideProgressBar(false)
    when (it) {
        is SocketTimeoutException -> showDialogWithException(context)
        is UnknownHostException -> showDialogWithException(context)
        else -> {
            if (it.message.equals(MESS_429)) {
                view?.showAnyError(context.getString(R.string.err_429))
            } else if (it.message.equals(MESS_422)) {
                view?.showAnyError(context.getString(R.string.err_422))
            }
        }
    }
}

Наконец, метод для отображения диалогового окна, предлагающего повторную попытку запроса при нажатии положительной кнопки:

fun showDialogWithException(context: Context) {
if (!(context as Activity).isFinishing) {
    DialogInternetUtils().showOkDialog(
            context,
            context.getString(R.string.no_internet_connection),
            DialogInterface.OnClickListener
            { dialogInterface, i ->
                dialogInterface?.dismiss()
                if (i == Dialog.BUTTON_NEGATIVE) {
                    dialogInterface!!.dismiss()
                    return@OnClickListener
                } else if (i == Dialog.BUTTON_POSITIVE) {
                    // here handle click button positive, need retry request
                }
            })
}

}

Пожалуйста, помогите мне закончить обработку нажатия на кнопку «+», чтобы повторить запрос. Я думаю, нужно обработать ошибку в методах .doOnError() или .onErrorResumeNext(), но я застрял здесь...


person nicolas asinovich    schedule 28.03.2018    source источник


Ответы (1)


Вы можете передать функцию, которая будет выполняться при нажатии кнопки диалога:

fun showDialogWithException(context: Context, action: () -> Unit) {
  if (!(context as Activity).isFinishing) {
    DialogInternetUtils().showOkDialog(
        context,
        context.getString(R.string.no_internet_connection),
        DialogInterface.OnClickListener
        { dialogInterface, i ->
          dialogInterface?.dismiss()
          if (i == Dialog.BUTTON_NEGATIVE) {
            dialogInterface!!.dismiss()
            return@OnClickListener
          } else if (i == Dialog.BUTTON_POSITIVE) {
            action()
          }
        })
  }
}
private fun handleAnyError(it: Throwable, context: Context, action: () -> Unit) {
  view?.showOrHideProgressBar(false)
  when (it) {
    is SocketTimeoutException -> showDialogWithException(context, action)
    is UnknownHostException -> showDialogWithException(context, action)
    else -> {
      if (it.message.equals(MESS_429)) {
        view?.showAnyError(context.getString(R.string.err_429))
      } else if (it.message.equals(MESS_422)) {
        view?.showAnyError(context.getString(R.string.err_422))
      }
    }
  }
}
override fun checkPhone(phone: String, context: Context) {
  view?.let {
    it.showOrHideProgressBar(true)
    apiManager.checkPhone(phone)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(Schedulers.io())
        .subscribe({ result ->
          view?.showOrHideProgressBar(false)
          if (result.user_exists) {
            view?.showLogin()
          } else {
            val code = result.confirmation_code
            confirmPhone(phone, code, context)
          }
        }, { error ->
          handleAnyError(error, context, { checkPhone(phone, context) })
        }).addToCompositeDisposable(compositeDisposable)
  }
}
person Leonardo Lima    schedule 28.03.2018
comment
это такое простое решение, в отличие от publishSubject в rxjava. Благодарность - person j2emanue; 28.07.2018