以下内容为原创,欢迎转载,转载请注明
来自天天博客:
Github:
EventBus的作用是发布/订阅事件总线,因为项目中用到RxJava、RxAndroid,所以完全可以使用RxJava、RxAndroid来实现EventBus。
1. 编写RxBus,用于存储所有事件Subjects。
事件是传递的最小单位,可以把任何类作为一个事件。
RxBus代码如下:
1 /** 2 * Author: wangjie 3 * Email: tiantian.china.2@gmail.com 4 * Date: 6/11/15. 5 */ 6 public class RxBus { 7 private static final String TAG = RxBus.class.getSimpleName(); 8 private static RxBus instance; 9 public static boolean DEBUG = false;10 11 public static synchronized RxBus get() {12 if (null == instance) {13 instance = new RxBus();14 }15 return instance;16 }17 18 private RxBus() {19 }20 21 private ConcurrentHashMap
如上述代码,RxBus只提供了register、unregister、post三个方法。
这里又加入了一个tag的概念,也可以理解为channel,注册Subject、反注册Subject和post事件的时候都需要这个tag,只有tag一致才能正常接收到事件。
比如有一个事件类HelloEvent,这个事件的作用是接收到后toast一个提示“hello”,如果两个Activity都注册了这个HelloEvent事件,但是没有tag去限制,一旦post了一个helloEvent事件后,两个Activity都会收到这个事件,导致两个Activity都会toast。如果使用tag,post这个HelloEvent的时候可以设置这个tag,只有register时也使用了这个tag才会接收到这个event。
2. 在Present(如Activity的onCreate)中注册一个Observer(以下以发送一个String类型的事件为例)
1 ObservableaddOb = RxBus.get()2 .register("addFeedTag", String.class);3 4 addOb.observeOn(AndroidSchedulers.mainThread())5 .subscribe(s -> {6 // todo: Accept event and process here7 });
如上,注册了一个String类型的事件,事件的tag是“addFeedTag”,用来增加一个Feed。使用RxAndroid在Action1中处理接收到的这个事件。
3. 在任何地方发送一个事件:
RxBus.get().post("addFeedTag", "hello RxBus!");
这里发送了一个tag为“addFeedTag”的String类型的事件。
4. 反注册Observer:
RxBus.get().unregister("addFeedTag", addOb);
注意:这里的Tag都为“addFeedTag”。
下面使用注解的方式更简单方便地使用RxBus(嗯-。-这里才是重点)。
首先来看下使用注解后的代码:
1. 注册Observer
这一步可以省略掉。
2. 发送一个事件(这里我们换一个事件:FeedItemClickEvent,我们定义这个事件是用来处理当Feed被点击后的事件)
RxBus.get().post(new FeedItemClickEvent().setPosition(position).setFeed(feed));
3. 接收事件,然后处理
1 @Accept2 public void onPostAccept(Object tag, FeedItemClickEvent event) {3 Logger.d(TAG, "onPostAccept event: " + event);4 Feed feed = event.getFeed();5 // 跳转到feed详情页面...6 }
如上,这里只需要编写一个方法,加上Accept注解,然后在方法中进行事件处理即可。
注意:方法名可以任意
方法参数一:必须为Object类型的tag;
方法参数二,如果这个方法只接收一种事件,则写明具体的事件类型,如上;如果这个方法接收多种事件,则类型需要为Object。
4. 反注册Observer
这一步也可以省略掉。
接收多种事件:
1 @Accept( 2 acceptScheduler = AcceptScheduler.NEW_THREAD, 3 value = { 4 @AcceptType(tag = ActionEvent.CLOSE, clazz = String.class), 5 @AcceptType(tag = ActionEvent.BACK, clazz = String.class), 6 @AcceptType(tag = ActionEvent.EDIT, clazz = String.class), 7 @AcceptType(tag = ActionEvent.REFRESH, clazz = String.class) 8 } 9 )10 public void onPostAccept(Object tag, Object actionEvent) {11 Logger.d(TAG, "[ActionEvent]onPostAccept action event name: " + actionEvent);12 // todo: Accept event and process here (in new thread)13 }
这里@Accept注解中设置了acceptScheduler为AcceptScheduler.NEW_THREAD,指明方法运行在子线程中.
value中指明了接收的事件类型,这里表示这个方法接收4种类型的事件:CLOSE, BACK, EDIT, REFRESH.
注解解释:
@Accept注解
acceptScheduler: 指定被注解的方法运行的Scheduler。
value[]: AcceptType注解数组,用于指定接收事件的tag和class。
@AcceptType注解:
tag: 接收事件的tag
clazz: 接收事件的类型
AcceptScheduler:
详情见:rx.schedulers.Schedulers和rx.android.schedulers.AndroidSchedulers
如果设置的是AcceptScheduler.EXECUTOR或AcceptScheduler.HANDLER,则需要在Application中配置Executor和Handler:
1 /** 2 * Author: wangjie 3 * Email: tiantian.china.2@gmail.com 4 * Date: 6/15/15. 5 */ 6 public class MyApplication extends Application { 7 private Executor acceptExecutor = Executors.newCachedThreadPool(); 8 private Handler handler = new Handler(Looper.getMainLooper()); 9 10 @Override11 public void onCreate() {12 super.onCreate();13 RxBus.DEBUG = true;14 15 DefaultAcceptConfiguration.getInstance().registerAcceptConfiguration(new DefaultAcceptConfiguration.OnDefaultAcceptConfiguration() {16 @Override17 public Executor applyAcceptExecutor() {18 return acceptExecutor;19 }20 21 @Override22 public Handler applyAcceptHandler() {23 return handler;24 }25 });26 }27 }
因为需要对Accept和AcceptType注解的解析,所以项目的BaseActivity需要使用,然后实现parserMethodAnnotations()方法,使用对注解进行解析。
参考: