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

Я использую MVVM и rxJava и модифицирую, чтобы отправить свой запрос. У меня есть нижняя навигационная панель, в которой есть 5 фрагментов, и в одном из них я должен отправить запрос, и после него ответ будет доставлен, я должен отправить еще один запрос на свой сервер. это мой класс ViewModel:

class MyViewModel: ViewModel() {

val compositeDisposable = CompositeDisposable()
val myFirstReqLiveData = MutableLiveData<myFirstReqModel>()
val mySecondReqLiveData = MutableLiveData<mySecondReqModel>()

    fun getFirstReq(token:String){

    val firstReqDisposable = RetrofitClientInstance.getRetrofitInterface()
        .getFirstReq(token)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()).singleElement()
        .subscribe({
                it-> myFirstReqLiveData.value = it
        },{
            errorFirstReqLiveData.value = it
        },{

        })
    compositeDisposable.add(firstReqDisposable)

}

    fun getSecondReq(token:String){

    val secondReqDisposable = RetrofitClientInstance.getRetrofitInterface()
        .getSecondReq(token)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()).singleElement()
        .subscribe({
                it-> mySecondReqLiveData.value = it
        },{
            errorSecondReqLiveData.value = it
        },{

        })
    compositeDisposable.add(SecondReqDisposable)

}

    override fun onCleared() {
    super.onCleared()
    compositeDisposable.clear()
}

}

а в своем фрагменте я реализую так:

class FirstTabFragment : Fragment() {
private lateinit var myViewModel: MyViewModel

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)

        getFirstReq(myViewModel, token!!)
        observeFirstReq(myViewModel)
        observeFirstReqError(myViewModel)

        observeSecondReq(myViewModel)
        observeSecondReqError(myViewModel)
}

    fun getFirstReq(viewModel: MyViewModel, token: String) {
    viewModel.getFirstReq(token)
}

   fun observeFirstReq(viewModel: MyViewModel) {
    viewModel.getFirstReqLiveData().observe(this, Observer { myFirstReqModel ->
   getSecondReq(myViewModel)
    }
   }

   fun getSecondReq(viewModel: MyViewModel, token: String) {
    viewModel.getSecondReq(token)
   }


    fun observeSecondReq(viewModel: MyViewModel) {
    viewModel.getSecondReqLiveData().observe(this, Observer { mySecondReqModel ->
   //do some work with my data
    }
   }

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

Я думаю, что назначаю новую подписку каждый раз, когда снова открываю свой фрагмент, поэтому он звонил несколько раз.

как я могу исправить эту проблему ?!


person Azin Nilchi    schedule 30.09.2019    source источник
comment
getFirstReqLiveData получает уведомление о времени при переключении вкладки. из-за чего он делает вызов API для второго запроса. Вы должны обернуть изменяемые живые данные в Event ‹T› и во фрагменте, вы должны наблюдать как EventObserver   -  person Kishan Maurya    schedule 30.09.2019
comment
@KishanMaurya, можешь объяснить больше? Я новичок в этом и не знаю, как реализовать то, что вы говорите   -  person Azin Nilchi    schedule 30.09.2019
comment
Пожалуйста, дайте мне знать, работает ли опубликованный код для вас .. иначе поделитесь кодом, я отлажу и сообщу вам причину   -  person Kishan Maurya    schedule 30.09.2019


Ответы (2)


Создать ниже класс

open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

в Viewmodel измените вот так

val myFirstReqLiveData = MutableLiveData<Event<myFirstReqModel>>()
val mySecondReqLiveData = MutableLiveData<Event<mySecondReqModel>>()

в классе Fragment

fun observeFirstReq(viewModel: MyViewModel) {
    viewModel.getFirstReqLiveData().observe(this, EventObserver { myFirstReqModel ->
   getSecondReq(myViewModel)
    }
   }

изменение

it-> myFirstReqLiveData.value = it to 
it-> myFirstReqLiveData.value = Event(it)

попробуйте использовать этот способ, если это вам поможет.

person Kishan Maurya    schedule 30.09.2019
comment
ты тоже можешь поделиться классом EventObserver ?! - person Azin Nilchi; 30.09.2019
comment
class EventObserver ‹T› (private val onEventUnhandledContent: (T) - ›Unit): Observer‹ Event ‹T› ›{override fun onChanged (event: Event ‹T›?) {event? .getContentIfNotHandled () ?. let {value - ›onEventUnhandledContent (значение)}}} - person Kishan Maurya; 30.09.2019
comment
добро пожаловать .. :) :) Вы можете узнать о событии и обозревателе событий в Интернете. - person Kishan Maurya; 30.09.2019

Вы также можете удалить getSecondReq(myViewModel) из наблюдателя и объединить или связать свои запросы.

https://github.com/ReactiveX/RxJava/wiki/Combining-Observables

Что-то вроде этого:

    val disposable = RetrofitClientInstance.getRetrofitInterface()
        .getFirstReq(token)
        .doOnError { errorFirstReqLiveData.value = it }
        .doOnNext { myFirstReqLiveData.value = it }
        .flatMap { t -> getSecondReq(token) }
        .doOnError { errorSecondReqLiveData.value = it }
        .doOnNext { mySecondReqLiveData.value = it }
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()).singleElement()
        .subscribe()
compositeDisposable.add(disposable)
person Vitalii Malyi    schedule 30.09.2019
comment
Я новичок в RxJava, я прочитаю об этом и использую ваш ответ в будущем, спасибо - person Azin Nilchi; 01.10.2019
comment
@AzinNilchi, пожалуйста :) Эта ссылка действительно полезна, я часто проверяю ее, чтобы увидеть все доступные варианты - person Vitalii Malyi; 01.10.2019