在 RxJava subscribeOn() 期间丢失事件

Losing Events during RxJava subscribeOn()

我使用 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 触发。但我不想使用任意延迟来确保触发正确的方法。 有没有其他方法可以确保发出所有事件?

感谢您的帮助。

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

这是 mosby 的内部问题,现已修复。

https://github.com/sockeqwe/mosby/issues/242

请使用最新快照:

com.hannesdorfmann.mosby3:mvi:3.0.4-SNAPSHOT

(参见 README)以验证现在一切正常。

请评论链接的 github 问题是否解决了您的问题。 谢谢

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

Schedulers.trampoline() 似乎正在解决的问题是更改到另一个线程需要很短的时间。这会导致事件丢失。所以留在同一个线程上可以解决这个问题。