RxJava 作为事件总线?
RxJava as event bus?
我开始学习 RxJava,到目前为止我很喜欢它。我有一个片段在单击按钮时与 activity 通信(用新片段替换当前片段)。 Google 建议使用 interface 来让片段与 activity 进行通信,但它太冗长了,我尝试使用广播接收器,它可以正常工作,但它有缺点。
自从我学习 RxJava 以来,我想知道从片段到活动(或片段到片段)进行通信是否是一个好的选择?如果是这样,使用 RxJava 进行此类通信的最佳方式是什么?我是否需要制作这样的事件总线 one 如果是这样,我是否应该制作一个总线实例并在全球范围内使用它(与主题一起使用)?
是的,在你学会如何做之后,它会非常棒。考虑以下单例 class:
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;
}
}
在您的 Activity 中准备好接收事件(例如在 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.
});
在你的 Fragment 中传递发生的事件:
UsernameModel.instanceOf().setString("Nick");
你的 activity 然后会做一些事情。
提示 1:将字符串更改为您喜欢的任何对象类型。
技巧 2:如果你有依赖注入,它也很有效。
更新:
我写的比较长article
目前我认为我对这个问题的首选方法是:
1.) 使用 "local" 总线来明确定义目的,而不是使用一个全局总线来处理整个应用程序中的所有内容(因此变得非常笨拙),并且只将它们插入您需要的地方。
例如你可能有:
- 用于在您的
Activity
和 ApiService
之间发送数据的总线。
- 一个总线用于在
Activity
中的多个 Fragment
之间进行通信。
- 将当前选择的应用程序主题颜色发送到所有
Activity
的总线,以便它们可以相应地为所有图标着色。
2.) 使用 Dagger(或者如果您愿意,也可以使用 AndroidAnnotations)使将所有内容连接在一起的痛苦减轻一些(并且还可以避免大量 static
实例)。这也使它更容易,例如。 G。有一个组件只处理存储和读取 SharedPreferences
中的登录状态 - 然后这个组件也可以直接连接到您的 ApiService
为所有请求提供会话令牌。
3.) 在内部随意使用 Subject
,但在通过调用 return subject.asObservable()
将它们交给 public 之前 "cast" 将它们交给 Observable
.这可以防止其他 类 将值推入不应允许的 Subject
。
Define events
public class Trigger {
public Trigger() {
}
public static class Increment {
}
public static class Decrement {
}
public static class Reset {
}
}
Event controller
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;
}
}
Register event listener wherever required
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");
}
});
Send/Fire event
MyApplication mApp = (App) getApplicationContext();
//increment
mApp
.reactiveTrigger()
.send(new Trigger.Increment());
//decrement
mApp
.reactiveTrigger()
.send(new Trigger.Decrement());
上述库的完整实现,示例 -> RxTrigger
我开始学习 RxJava,到目前为止我很喜欢它。我有一个片段在单击按钮时与 activity 通信(用新片段替换当前片段)。 Google 建议使用 interface 来让片段与 activity 进行通信,但它太冗长了,我尝试使用广播接收器,它可以正常工作,但它有缺点。
自从我学习 RxJava 以来,我想知道从片段到活动(或片段到片段)进行通信是否是一个好的选择?如果是这样,使用 RxJava 进行此类通信的最佳方式是什么?我是否需要制作这样的事件总线 one 如果是这样,我是否应该制作一个总线实例并在全球范围内使用它(与主题一起使用)?
是的,在你学会如何做之后,它会非常棒。考虑以下单例 class:
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;
}
}
在您的 Activity 中准备好接收事件(例如在 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.
});
在你的 Fragment 中传递发生的事件:
UsernameModel.instanceOf().setString("Nick");
你的 activity 然后会做一些事情。
提示 1:将字符串更改为您喜欢的任何对象类型。
技巧 2:如果你有依赖注入,它也很有效。
更新: 我写的比较长article
目前我认为我对这个问题的首选方法是:
1.) 使用 "local" 总线来明确定义目的,而不是使用一个全局总线来处理整个应用程序中的所有内容(因此变得非常笨拙),并且只将它们插入您需要的地方。
例如你可能有:
- 用于在您的
Activity
和ApiService
之间发送数据的总线。 - 一个总线用于在
Activity
中的多个Fragment
之间进行通信。 - 将当前选择的应用程序主题颜色发送到所有
Activity
的总线,以便它们可以相应地为所有图标着色。
2.) 使用 Dagger(或者如果您愿意,也可以使用 AndroidAnnotations)使将所有内容连接在一起的痛苦减轻一些(并且还可以避免大量 static
实例)。这也使它更容易,例如。 G。有一个组件只处理存储和读取 SharedPreferences
中的登录状态 - 然后这个组件也可以直接连接到您的 ApiService
为所有请求提供会话令牌。
3.) 在内部随意使用 Subject
,但在通过调用 return subject.asObservable()
将它们交给 public 之前 "cast" 将它们交给 Observable
.这可以防止其他 类 将值推入不应允许的 Subject
。
Define events
public class Trigger {
public Trigger() {
}
public static class Increment {
}
public static class Decrement {
}
public static class Reset {
}
}
Event controller
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;
}
}
Register event listener wherever required
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");
}
});
Send/Fire event
MyApplication mApp = (App) getApplicationContext();
//increment
mApp
.reactiveTrigger()
.send(new Trigger.Increment());
//decrement
mApp
.reactiveTrigger()
.send(new Trigger.Decrement());
上述库的完整实现,示例 -> RxTrigger