在RxJava中丢失事件subscribeOn()

时间:2017-04-28 13:00:32

标签: android rx-java2 mosby

我使用Mosby获得了以下代码。

片段:

@Override
public Observable<CardInfo> loadCardIntent() {
    return Observable.just(new CardInfo(cardselected, PreferenceManager.getDefaultSharedPreferences(getContext())
            .getBoolean(PreferencesVariables.SHOW_BACK_CARD.toString(), false)))
            //.delay(500, TimeUnit.MILLISECONDS)
            .doOnNext(showBack -> Log.d(TAG, "Show card back: " + showBack));
 }

@Override
 public Observable<CardInfo> loadFrontIntent() {
        return RxView.clicks(cardBackImageView)
                .map(showFront -> new CardInfo(cardselected, false))
                .doOnNext(showFront -> Log.d(TAG, "Show card front"));
}

@Override
public Observable<Boolean> hideCardIntent() {
        return clicks(cardFrontImageView)
                .map(ignored -> true)
                .doOnNext(close -> Log.d(TAG, "Close card activity"));
}

主讲人:

@Override
    protected void bindIntents() {

        Observable<CardViewState> showSelectedCard = intent(CardView::loadCardIntent)
                .switchMap(cardInfo -> interactor.getCard(cardInfo))
                .doOnError(error -> System.out.print(error.getMessage()));

        Observable<CardViewState> showFront = intent(CardView::loadFrontIntent)
                .switchMap(cardInfo -> interactor.getCard(cardInfo))
                .doOnError(error -> System.out.print(error.getMessage()));

        Observable<CardViewState> hideCard = intent(CardView::hideCardIntent)
                .switchMap(ignored -> interactor.hideCard());

        Observable<CardViewState> intents = Observable.merge(showSelectedCard, showFront, hideCard)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

        subscribeViewState(intents, CardView::render);
    }

片段:

@Override
public void render(CardViewState viewState) {
    if (viewState instanceof CardViewState.CardBackState) {
        renderCard(R.raw.planningpoker_rueckseite, cardBackImageView);
        renderCard(((CardViewState.CardBackState) viewState).card, cardFrontImageView);
        showCardBack();
    } else if (viewState instanceof CardViewState.CardFrontState) {
        renderCard(R.raw.planningpoker_rueckseite, cardBackImageView);
        renderCard(((CardViewState.CardFrontState) viewState).card, cardFrontImageView);
        showCardFront();
    } else if (viewState instanceof CardViewState.CardCloseState) {
        getActivity().finish();
    }
}

交互器:

Observable<CardViewState> getCard(CardInfo cardInfo) {
    return cardInfo.showBack ? Observable.just(new CardViewState.CardBackState(CARDS[cardInfo.card])) :
            Observable.just(new CardViewState.CardFrontState(CARDS[cardInfo.card]));
}

Observable<CardViewState> hideCard() {
    return Observable.just(new CardViewState.CardCloseState());
}

没有loadCardIntent()的延迟,render() - 方法不会被CardBackState触发。但我不想使用任意延迟来确保触发正确的方法。 有没有其他方法可以确保所有事件都被发出?

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

嗯,您的代码是否可以在github上找到?到目前为止,一切似乎都没问题。也许这是一个内部的mosby bug。如果在演示者bind()方法中将subscribeOn(schdulers.io())添加到loadCardIntent(),它是否有效。 我看到有或没有delay​()的唯一区别是你的代码运行同步(在主UI线程上),而delay()将代码的执行切换到后台线程。你确定你的interactor.getCardInfo()是要在orroids主UI线程上运行吗?即如果它在主线程上运行,但您正在执行http请求(在主UI线程上),则抛出异常。你是否在交互者中捕获异常?

答案 1 :(得分:0)

我现在的解决方案是使用Schedulers.trampoline()。它不是理想的,也不是足够的,但它让我摆脱了更麻烦的延迟。

Schedulers.trampoline()似乎要解决的问题是对另一个线程的更改需要很短的时间。这导致事件迷失。所以保持相同的线程修复了这一点。