RxJava作为事件总线?

时间:2015-09-24 17:20:06

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

我开始学习RxJava,到目前为止我喜欢它。我有一个片段与按钮单击时的活动进行通信(用新片段替换当前片段)。谷歌建议interface片段与活动进行通信,但是它太冗长了,我试图使用普遍适用的广播接收器,但它有缺点。

因为我正在学习RxJava,我想知道从片段到活动(或片段到片段)的沟通是否是一个很好的选择?如果是这样,那么使用RxJava进行此类通信的最佳方式是什么?我是否需要制作像one这样的事件总线,如果是这种情况,我应该制作一个总线的单个实例并在全局(使用主题)中使用它吗?

3 个答案:

答案 0 :(得分:10)

是的,在你学会了如何做之后,这真是太神奇了。考虑以下单例类:

public class UsernameModel {

    private static UsernameModel instance;

    private PublishSubject<String> subject = PublishSubject.create();

    public static UsernameModel instanceOf() {
        if (instance == null) {
            instance = new UsernameModel();
        }
        return instance;
    }

    /**
     * Pass a String down to event listeners.
     */
    public void setString(String string) {
        subject.onNext(string);
    }

    /**
     * Subscribe to this Observable. On event, do something e.g. replace a fragment
     */
    public Observable<String> getStringObservable() {
        return subject;
    }

}

在您的活动中准备好接收事件(例如,将它放在onCreate中):

UsernameModel usernameModel = UsernameModel.instanceOf();

//be sure to unsubscribe somewhere when activity is "dying" e.g. onDestroy
subscription = usernameModel.getStringObservable()
        .subscribe(s -> {
            // Do on new string event e.g. replace fragment here
        }, throwable -> {
            // Normally no error will happen here based on this example.
        });

在你片段中,当事件发生时传递事件:

UsernameModel.instanceOf().setString("Nick");

您的活动将会有所作为。

提示1:使用您喜欢的任何对象类型更改String。

提示2:如果你有依赖注入,它也很有用。

<强>更新 我写了一篇更长的article

答案 1 :(得分:2)

目前我认为我对此问题的首选方法是:

1。)而不是一个全局总线处理整个应用程序中的所有内容(并因此变得非常笨重),使用&#34; local&#34;公共汽车有明确定义的目的,只能将它们插入您需要的地方。

例如,你可能有:

  • 一条总线,用于在ActivityApiService之间发送数据。
  • 一条总线,用于在Fragment中的多个Activity之间进行通信。
  • 一条总线,将当前选定的应用主题颜色发送到所有Activity,以便他们可以相应地着色所有图标。

2。)使用Dagger(或者如果您愿意,也可以使用AndroidAnnotations)使布线 - 所有内容 - 一起减少痛苦(并避免大量static个实例)。这也使得更容易,例如。 G。只有一个组件只处理存储和读取SharedPreferences中的登录状态 - 然后该组件也可以直接连接到您的ApiService,为所有请求提供会话令牌。

3.。)随意在内部使用Subject但是&#34;施放&#34;将他们发送给Observable,然后致电return subject.asObservable()将其发送给公众。这可以防止其他类将值推送到Subject,而不应该允许这些值。

答案 2 :(得分:0)

  

定义事件

public class Trigger {

public Trigger() {
}

public static class Increment {
}

public static class Decrement {
}

public static class Reset {
}
}
  

事件控制器

public class RxTrigger {

private PublishSubject<Object> mRxTrigger = PublishSubject.create();

public RxTrigger() {
    // required
}

public void send(Object o) {
    mRxTrigger.onNext(o);
}

public Observable<Object> toObservable() {
    return mRxTrigger;
}
// check for available events
public boolean hasObservers() {
    return mRxTrigger.hasObservers();
}
}
  

Application.class

public class App extends Application {

private RxTrigger rxTrigger;

public App getApp() {
    return (App) getApplicationContext();
}

@Override
public void onCreate() {
    super.onCreate();
    rxTrigger = new RxTrigger();
}


public RxTrigger reactiveTrigger() {
    return rxTrigger;
}


}
  

在需要的地方注册事件监听器

               MyApplication mApp = (App) getApplicationContext();
               mApp
                    .reactiveTrigger() // singleton object of trigger
                    .toObservable()
                    .subscribeOn(Schedulers.io()) // push to io thread
                    .observeOn(AndroidSchedulers.mainThread()) // listen calls on main thread
                    .subscribe(object -> { //receive events here
                        if (object instanceof Trigger.Increment) {
                            fabCounter.setText(String.valueOf(Integer.parseInt(fabCounter.getText().toString()) + 1));
                        } else if (object instanceof Trigger.Decrement) {
                            if (Integer.parseInt(fabCounter.getText().toString()) != 0)
                                fabCounter.setText(String.valueOf(Integer.parseInt(fabCounter.getText().toString()) - 1));
                        } else if (object instanceof Trigger.Reset) {
                            fabCounter.setText("0");
                        }
                    });
  

发送/火灾事件

 MyApplication mApp = (App) getApplicationContext();
 //increment
 mApp
    .reactiveTrigger()
    .send(new Trigger.Increment());

 //decrement
 mApp
    .reactiveTrigger()
    .send(new Trigger.Decrement());

使用示例完整实现上述库 - &gt; RxTrigger