Tsudzukeru
@Tsudzukeru

Как правильно очистить ресурсы во вложенном запросе RxJava?

Учусь рабоать с RxJava, вызывая методы Youtube Api.
Для того чтобы получить информацию о видео - нужно вызвать 2 метода:
1)searchVideos - чтобы получить идентификаторы видео по строке запроса;
2)videoInfo - позволяет получить нужною информацию о видео по его id;

Пишу вот такой метод:
fun getVideos(query:String){
        activityContract.showProgressBar()
        api.searchVideos(query)
            .doOnError {
                Log.e("searchVideosError",it.message)
                if (it.message.toString() == "HTTP 403 "){
                    activityContract.showErrorDialog("API limit exceeded")
                }
                else {
                    activityContract.showErrorDialog(it.message.toString())
                }
                activityContract.hideProgressBar()
                disposables.dispose()
            }
            .onErrorReturnItem(mutableListOf(Video("ErrorId")))
            .subscribeOn(Schedulers.io())
            .flatMap{ Observable.fromIterable(it)}
            .flatMap {api.videoInfo(it.videoId)}
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnError {
                Log.e("videoInfoError",it.message)
                if (it.message.toString() == "HTTP 403 "){
                    activityContract.showErrorDialog("API limit exceeded")
                }
                else {
                    activityContract.showErrorDialog(it.message.toString())
                }
                activityContract.hideProgressBar()
                disposables.dispose()
            }
            .onErrorReturnItem(Video("ErrorId"))
            .toList()
            .subscribeBy {
                viewModel.saveSearchResults(it)
                activityContract.hideProgressBar()
            }.addTo(disposables)
    }


Код работает. Меня интересует две вещи:
1)Правильно ли я очищаю ресурсы? Вызываются то 2 метода, а в disposables добавляю только один раз, в самом конце метода.
2)Как правильно прервать дальнейшее выполнение методов в случае ошибки? В doOnError - отлавливаю 403 ошибку. Если 403 ошибка происходит - то вызываю disposables.dispose() и показываю фрагмент с ошибкой. На смартфоне всё работает, но на эмуляторе всёровно происходит дальнейший вызов методов и я ловлю FATAL EXCEPTION.
  • Вопрос задан
  • 78 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Java
Android developer at Yandex
Нет, всё очень плохо, так Rx использовать нельзя.
Внутри цепочки сайдэффекты нужно минимизировать, они у тебя на любой чих.
Внутри цепочки не должно быть никаких "освобождений ресурсов" в виде disposables.dispose(). dispose должен быть только вне цепочки. Тем более, что неизвестно, что ты напихал ещё в этот disposable. Зафейлилась одна цепочка - и всё, работа встала полностью, потому что больше ничего ты в этот disposables запихать не сможешь. clear() надо вызывать в случае, когда тебе нужно очистить CompositeDisposable.
.flatMap{ Observable.fromIterable(it)} это вообще что за дичь бессмысленная? просто удали эту строку и ничего не изменится.
Обычно методы типа getVideos что-то возвращают. В твоем случае это должен быть по ситуации Observable/Single.
.onErrorReturnItem(mutableListOf(Video("ErrorId")))
Дичь. Мутабельные данные в стриме - путь в никуда. Только иммутабельные. ErrorId? Orly? Сделай ты sealed класс, в конце концов.
Почитай про SOLID, этот твой метод делает слишком много всего.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы