- 解惑
AndroidEventBus:区别于greenrobot的EventBus,是由国内大神进行写类似EventBus也是在此基础上升华的一个开源库,是和greenrobot的EventBus完全是两个不独立的开源项目,一开始我也是摸不清两者以为 都是同一个大神写后来发现是两个不同的开源库。
概述:
AndroidEventBus类似于观察者模式,通过register函数将需要订阅事件的对象注册到事件总线中,然后根据@Subscriber注解来查找对象中的订阅方法,并且将这些订阅方法和订阅对象存储在map中。当用户在某个地方发布一个事件时,事件总线根据事件的参数类型和tag找到对应的订阅者对象,最后执行订阅者对象中的方法。这些订阅方法会执行在用户指定的线程模型中,比如mode=ThreadMode.ASYNC则表示该订阅方法执行在子线程中
- 区别:1:greenrobot的EventBus 2:AndroidEventBus
greenrobot的EventBus是一个非常流行的开源库,但是它在使用体验上并不友好,例如它的订阅函数必须以onEvent开头,并且如果需要指定该函数运行的线程则又要根据规则将函数名加上执行线程的模式名,这么说很难理解,比如我要将某个事件的接收函数执行在主线程,那么函数名必须为onEventMainThread。那如果我一个订阅者中有两个参数名相同,且都执行在主线程的接收函数呢? 这个时候似乎它就没法处理了。而且规定死了函数命名,那就不能很好的体现该函数的功能,也就是函数的自文档性;
AndroidEventBus使用注解来标识接收函数,这样函数名不受限制,比如我可以把接收函数名写成updateUserInfo(Person info),这样就灵活得多了。 另一个不同就是AndroidEventBus增加了一个额外的tag来标识每个接收函数可接收的事件的tag,这类似于Broadcast中的action,比如每个Broadcast对应一个或者多个action,当你发广播时你得指定这个广播的action,然后对应的广播接收器才能收到
- 使用AndroidEventBus
你可以按照下面几个步骤来使用AndroidEventBus. * 1. 注册事件接收对象 public class YourActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); // 注册对象 EventBus.getDefault().register(this); } @Override protected void onDestroy() { // 注销 EventBus.getDefault().unregister(this); super.onDestroy(); } } * 2. 通过Subscriber注解来标识事件接收对象中的接收方法 public class YourActivity extends Activity { // code ...... // 接收方法,默认的tag,执行在UI线程 @Subscriber private void updateUser(User user) { Log.e("", "### update user name = " + user.name); } // 含有my_tag,当用户post事件时,只有指定了"my_tag"的事件才会触发该函数,执行在UI线程 @Subscriber(tag = "my_tag") private void updateUserWithTag(User user) { Log.e("", "### update user with my_tag, name = " + user.name); } // 含有my_tag,当用户post事件时,只有指定了"my_tag"的事件才会触发该函数, // post函数在哪个线程执行,该函数就执行在哪个线程 @Subscriber(tag = "my_tag", mode=ThreadMode.POST) private void updateUserWithMode(User user) { Log.e("", "### update user with my_tag, name = " + user.name); } // 含有my_tag,当用户post事件时,只有指定了"my_tag"的事件才会触发该函数,执行在一个独立的线程 @Subscriber(tag = "my_tag", mode = ThreadMode.ASYNC) private void updateUserAsync(User user) { Log.e("", "### update user async , name = " + user.name + ", thread name = " + Thread.currentThread().getName()); } } User类大致如下 : public class User { String name ; public User(String aName) { name = aName ; } }
接收函数使用tag来标识可接收的事件类型,与BroadcastReceiver中指定action是一样的,这样可以精准的投递消息。mode可以指定目标函数执行在哪个线程,默认会执行在UI线程,方便用户更新UI。目标方法执行耗时操作时,可以设置mode为ASYNC,使之执行在子线程中。
* 3. 在其他组件,例如Activity, Fragment,Service中发布事件 EventBus.getDefault().post(new User("android")); // post a event with tag, the tag is like broadcast's action EventBus.getDefault().post(new User("mr.simple"), "my_tag");
发布事件之后,注册了该事件类型的对象就会接收到响应的事件.
基本的使用和greenrobot EventBus相差不多,个人感觉这种注解的方式更好用。
实现形式和greenobot的EventBus实现过程差不多,通过反射获取注解找到对应的方法进行动态执行。AndroidEventBus源码中是有中文注释,写的很详细想看的可以下载下来看看。