在 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()
似乎正在解决的问题是更改到另一个线程需要很短的时间。这会导致事件丢失。所以留在同一个线程上可以解决这个问题。
我使用 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()
似乎正在解决的问题是更改到另一个线程需要很短的时间。这会导致事件丢失。所以留在同一个线程上可以解决这个问题。