我开始学习RxJava,到目前为止我很喜欢它。我有一个片段,与按钮单击活动通信(用新片段替换当前片段)。谷歌推荐的接口片段通信到活动,但它太啰嗦,我试图使用广播接收器,一般工作,但它有缺点。
因为我正在学习RxJava,我想知道从片段到活动(或片段到片段)通信是否是个好选择?如果是这样,使用RxJava进行这种类型的通信的最佳方式是什么?我是否需要使事件总线像这样,如果是这种情况下,我应该使总线的单个实例,并使用它全局(与主题)?
是的,当你学会如何去做之后,它是相当惊人的。考虑下面的单例类:
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:如果你有依赖注入,它也会工作得很好。
更新:我写了一篇更长的文章
目前我认为我对这个问题的首选方法是:
1)。而不是一个全局总线处理整个应用程序的一切(因此变得相当笨拙),使用"本地"总线为明确定义的目的,只在你需要它们的地方插入它们。
例如:
- 在
Activity
和ApiService
之间发送数据的总线。 -
Activity
中多个Fragment
之间通信的总线。 - 将当前选择的应用程序主题颜色发送给所有
Activity
的总线,以便他们可以相应地着色所有图标。
2)。使用Dagger(或者如果您喜欢的话,也可以使用AndroidAnnotations)将所有东西连接在一起时不那么痛苦(并且还可以避免大量的static
实例)。这也使它更容易,例如,有一个单独的组件,只处理存储和读取登录状态在SharedPreferences
-这个组件也可以直接连接到您的ApiService
,为所有请求提供会话令牌。
3)。您可以随意在内部使用Subject
,但在通过调用return subject.asObservable()
向公众发布它们之前,将它们"强制转换"到Observable
。这可以防止其他类将不应该被允许的值压入Subject
。
定义事件
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());
以上库的完整实现,示例-> RxTrigger