java 事件重复执行_android – RxJava作为事件总线,当只有一个事件发布时,onNext被多次调用...

我正在用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 mBusSubject = new SerializedSubject<>(PublishSubject.create());

public static RxBus getInstance() {

return INSTANCE;

}

public Subscription register(final Class eventClass, Action1 onNext) {

return mBusSubject

.filter(new Func1() {

@Override

public Boolean call(Object event) {

return event.getClass().equals(eventClass);

}

})

// .filter(event -> event.getClass().equals(eventClass))

.map(new Func1() {

@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));

}

});

}

}

从Fragment订阅活动

@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() {

@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() {

@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.unsubscribe();和mApplyTagSubscription.unsubscribe();在onStop()中.

PublishSubject用于事件总线. PublishSubject是一个主题:

Subject that, once an Observer has subscribed, emits all subsequently observed items to the subscriber.

因此,如果您不取消订阅()订阅,此订阅将“记录”历史记录中发生的所有事件,并发出一次.subscribe(onNext)执行.

标签:android,rx-java,rx-android,event-bus

来源: https://codeday.me/bug/20190527/1167111.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是JavaAndroid retrofit okhttp rxjava代码的示例: 首先,在build.gradle文件中添加以下依赖: ``` implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxjava:2.2.10' ``` 然后,在你的Java类中,创建一个Retrofit实例: ```java public class RetrofitClient { private static Retrofit retrofit = null; public static Retrofit getClient(String baseUrl) { if (retrofit==null) { retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .client(getOkhttpClient()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } return retrofit; } private static OkHttpClient getOkhttpClient() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); return new OkHttpClient.Builder().addInterceptor(interceptor).build(); } } ``` 接下来,在你的Activity或Fragment中,定义一个接口: ```java public interface ApiService { @GET("api/data/{category}/{count}/{page}") Observable<Results> getData(@Path("category") String category, @Path("count") int count, @Path("page") int page); } ``` 在这个示例中,我们使用了Retrofit和RxJava获取远程数据。 最后,在你的代码中,调用Retrofit客户端并使用RxJava观察获取到的数据: ```java ApiService apiService = RetrofitClient.getClient(BASE_URL).create(ApiService.class); apiService.getData(category, count, page) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<Results>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Results results) { // 处理从服务器获取到的数据 } @Override public void onError(Throwable e) { // 处理请求错误 } @Override public void onComplete() { } }); ``` 这就是一个简单的Android retrofit okhttp rxjava代码的示例。当然,具体的实现方式会根据不同的需求而有所变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值