我正在用RxJava实现一个事件总线(RxBus)。
RxBus。Java语言
public class RxBus {
private static final String TAG = LogUtils.makeTag(RxBus.class);
private static final RxBus INSTANCE = new RxBus();
private final Subject<Object, Object> mBusSubject = new SerializedSubject<>(PublishSubject.create());
public static RxBus getInstance() {
return INSTANCE;
}
public <T> Subscription register(final Class<T> eventClass, Action1<T> onNext) {
return mBusSubject
.filter(new Func1<Object, Boolean>() {
@Override
public Boolean call(Object event) {
return event.getClass().equals(eventClass);
}
})
// .filter(event -> event.getClass().equals(eventClass))
.map(new Func1<Object, T>() {
@Override
public T call(Object obj) {
return (T) obj;
}
})
// .map(obj -> (T) obj)
.subscribe(onNext);
}
public void post(Object event) {
Log.d(TAG, "Apr12, " + "post event: " + event);
mBusSubject.onNext(event);
}
}
从RecyclerView的viewHolder发布事件
public ViewHolder(LayoutInflater inflater, final ViewGroup parent) {
super(inflater.inflate(R.layout.bill_card, parent, false));
drawee = (SimpleDraweeView) itemView.findViewById(R.id.card_image);
title = (TextView) itemView.findViewById(R.id.card_title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Apr12, item clicked.");
RxBus.getInstance().post(new ItemSelectedEvent(position));
}
});
TagImageButton = (ImageButton) itemView.findViewById(R.id.tag_button);
TagImageButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Log.d(TAG, "Tag button clicked.");
RxBus.getInstance().post(new ApplyTagForItemEvent(position));
}
});
}
}
从片段订阅事件
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mActivity = getActivity();
Log.d(TAG, "getActivity(): " + getActivity());
mItemClickSubscription = RxBus.getInstance().register(ItemSelectedEvent.class,
new Action1<ItemSelectedEvent>() {
@Override
public void call(ItemSelectedEvent event) {
Log.d(TAG, "Apr12, " + "call event: " + event);
if (mDetail == null) {
if (getParentFragment() instanceof IFragmentStackHolder) {
IFragmentStackHolder fsh = (IFragmentStackHolder) getParentFragment();
Fragment details = new DetailCardFragment();
Bundle args = new Bundle();
args.putInt(ContentHolder.INDEX, event.getPosition());
details.setArguments(args);
fsh.pushFragment(details, event.getPairs());
}
}
}
});
mApplyTagSubscription = RxBus.getInstance().register(ApplyTagForItemEvent.class,
new Action1<ApplyTagForItemEvent>() {
@Override
public void call(ApplyTagForItemEvent event) {
IFragmentStackHolder fsh = (IFragmentStackHolder) getParentFragment();
Fragment tagApplyFragment = new TagApplyFragment();
Bundle args = new Bundle();
args.putInt(ContentHolder.INDEX, event.getPosition());
tagApplyFragment.setArguments(args);
fsh.pushFragment(tagApplyFragment, null);
}
}
);
}
问题是:当我点击itemView
或TagImageButton
时,RxBus.post()
只被调用一次(这是正确的),但是Action1 call()
被多次调用(甚至不是常量时间)。请参阅下面的日志。
D/**-CardContentView(31177): Apr12, item clicked.
D/**-RxBus(31177): Apr12, post event: com.*****.events.ItemSelectedEvent@1a11346e
D/**-CardDetailFragment(31177): Apr12, call event: com.*****.events.ItemSelectedEvent@1a11346e
D/**-CardDetailFragment(31177): Apr12, call event: com.*****.events.ItemSelectedEvent@1a11346e
D/**-CardDetailFragment(31177): Apr12, call event: com.*****.events.ItemSelectedEvent@1a11346e
我怎样才能让它只打一次电话?
编辑:我发现如果Action1 call()
这次被调用N次,下次当我单击该项目时将被调用N 1次。似乎可观察对象正在向订阅者发出历史记录中所有随后观察到的项目。
最终找到解决方案。
非常简单:我应该调用mItemClickSubscription。取消订阅() 和映射标签订阅。取消订阅() 在顶部()中。
在事件总线中使用PublishSubjectPublishSubject是一个主题:
主题,一旦观察者订阅,则向订阅者发送所有随后观察到的项目。
因此,如果您不取消订阅,此订阅将保留“记录”历史中发生的所有事件,并一次性发出所有事件。执行订阅(onNext)
。
问题内容: 为什么在组合框中选择项目时会两次调用此事件? 问题答案: 对于一次更改,JComoboBox ItemListener确实会被调用两次。一次用于SELECTED事件,一次用于DESELECTED事件。 有关如何编写ItemListener的信息,请参见本教程页面。 基本上你要做的就是
我在CQRS/ES设计中有一个计时案例。为了便于讨论,让我们以Microsoft关于这个主题的示例会议管理为基础(https://msdn.microsoft.com/en-us/library/jj554200.aspx)。 假设在第1分钟创建会议(最大座位数为20)。 在第4分钟,事件到达order mgmt上下文,因此创建了一个座位可用性。 在第7分钟,用户下了一个订单(通过订单管理),购买
我在JavaFX中创建了一个应用程序,其中有很多选择框(大约100个)。单击它们中的每一个会更改一个布尔变量的状态(选中-真,未选中-假)。我对每个选择框都有ActionEvent,但我想制作支持所有它们的操作事件。 其中一个ActionEvent看起来像: 第二个看起来很相似: 我从我的朋友那里听说我应该使用EventHandler创建类并传递参数(复选框和布尔变量),但我不知道怎么做。有什么解
让我们跳进 API 获取事件总线 你获取到事件总线的引用,如下所示: EventBus eb = vertx.eventBus(); 还有每个 Vert.x 实例事件总线的单个实例。 注册处理程序 这个最简单的方法来注册一个处理程序用consumer。下面是一个示例: EventBus eb = vertx.eventBus(); eb.consumer("news.uk.sport", mess
问题内容: 为了了解Spring事务的工作原理,我想知道在以下情况下发生的情况:如果一种方法标记为,而另一种方法标记为。 假设配置使用所有默认设置。 现在,如果我要输入,显然可以开始交易。然后,钻进去会发生什么?交易已经存在的事实会导致没有新的交易诞生,还是我在这里创建两个交易? 关于Propagation的文档(在下面引用)似乎涵盖了这一点,但是我想验证一下我的理解 Propagation:通常
我有一个服务类,它的方法doSomething()用@transactional进行了注释,传播类型为“required”。另一个非事务类调用了doSomething()两次。 我假设将有2个事务,为每个调用创建,但结果是两个调用只使用相同的事务。为了进一步混淆我,我使用另一个@RestController非事务性类调用了doThings()两次。但这次结果是每个调用使用不同的事务。 我有两个问题