Как использовать RxJava в обычном вызове дооснащения? - PullRequest
0 голосов
/ 16 марта 2019

Контекст : Мое текущее приложение использует обычный retrofit calls для получения данных из api.Я действительно хотел ввести RX в звонки, но у меня нет большого опыта с этим.Я читаю некоторые вещи в Интернете, и ни одна из них не показывает мне простой способ сделать это.Я покажу вам, что у меня есть.

Цель : Превратить то, что у меня есть, в RXJava

Это мой код:

Мой общий метод выполнения вызова, который я хочу преобразовать в RXJava:

fun <T> performCall(call: Call<T>?, callback: OnRequestCallback<T>) {
        call?.enqueue(object : Callback<T> {
            override fun onResponse(call: Call<T>, response: Response<T>) {
                when (response.code()) {
                    200, 201 -> {
                        callback.onSuccess(response.body())
                    }
                    else -> {
                        callback.onError(response.errorBody())
                    }
                }
                return
            }

            override fun onFailure(call: Call<T>, t: Throwable) {
                callback.onError(null)
                Log.d("Network Manager Failure", t.localizedMessage)
            }
        })
    }

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

fun <T> BaseActivity.callAPI(call: Observable<T>?, onSucceed: (T?) -> Unit, onError: (errorCode: String) -> Unit) {
    NetworkManager.instance.performCall(call,
        object : NetworkManager.OnRequestCallback<T> {
            override fun onSuccess(body: T?) {
                onSucceed(body)
            }

            override fun onError(errorResponseBody: ResponseBody?) {
                JSONObject(errorResponseBody?.string()).let {
                    val errorCode = it.getJSONObject("meta").getString("errorCode")
                    when (errorCode) {
                        Errors.DEPRECATED_API_VERSION.name ->
                            onAppUpdateNeeded()

                        else -> onError(errorResponseBody)
                    }
                }
            }
        })
}

Затем BaseActivitt.callApi() используется в каждом действии, для которого требуется информация API, теперь я использую view models + dagger лучше, но сейчас это то, что у меня есть, и я должен его сохранить.

Может кто-нибудь показать мне, как превратить это в RXJava/Kotlin вещь?

1 Ответ

0 голосов
/ 18 марта 2019

Если честно, мне не нравится идея иметь эти универсальные обработчики. Мне пришлось работать над проектом, который был написан таким образом, и это не было приятным опытом: что произойдет, если, например, вы захотите обработать Errors.DEPRECATED_API_VERSION другим способом для вызова?

В любом случае, я бы сделал что-то вроде этого: из Retrofit верните Observable, а затем в то место, где вам нужно сделать вызов, подпишитесь на Observable.

val disposable = service
        .yourApi()
        .map { value ->
            MyCommand.SuccessCommand(value)
        }
        .onErrorResumeNext { ex: Throwable -> YourObservableThatEmitsTheErrorCommandOrTheOnAppUpdateNeededCommand() }
        .subscribe { command: MyCommand ->
            when (command) {
                is MyCommand.SuccessCommand -> {
                }
                is MyCommand.ErrorCommand -> {

                }
                is MyCommand.AppUpdateNeededCommand -> {

                }
            }
        }

Команда может быть реализована что-то вроде

sealed class MyCommand {
    class SuccessCommand<T> (value: T): MyCommand()
    class ErrorCommand (val ex: Exception): MyCommand()
    object AppUpdateNeededCommand: MyCommand()
}
...