implementation 'org.greenrobot:eventbus:3.1.1'
3.角色分配发布者(publisher):用于发出事件
订阅者(subscriber):用于接收事件
事件(Event):事件本体
4.操作 发布者(Publisher):bt_01.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EventMessage msg = new EventMessage(1,"hello event");//这里的EventMessage是自己定义的用于传输数据的类 EventBus.getDefault().post(msg);//简单情况下常用方式 }});
接收者(Subscriber):在需要接收Event的Activity中注册EventBus,并在结束后销毁。
编写函数,添加注释后,用于获取事件的内容。
@Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this);//根据activity的生命周期onStop()或onDestroy(),与注册的状态,调整是否需要判断注册的状态 // if(!EventBus.getDefault().isRegistered(this)){// EventBus.getDefault().register(this);// } } @Override protected void onStop() { super.onStop();//官方在onStop()中进行解注册,根据实际情况可以调整到onDestroy(),e.g.(当在不同的activity间进行切换时,onStop()会在切换Activity时回调,此时会被取消注册) EventBus.getDefault().unregister(this); } @Subscribe(threadMode = ThreadMode.MAIN) public void onReceiveMsg(EventMessage message) { Log.e("MenuAc", "onReceiveMsg: " + message.toString()); }
4.1 ThreadMode属性的几种类型:POSTING, MAIN, MAIN_ORDERED, BACKGROUND, ASYNC
POSTING 默认情况,订阅者将会在发送事件的线程中被直接调用。事件交付意味着开销最小,因为它完全避免了线程切换。因此,这是当已知在很短时间内不需要主线程就能完成的简单任务所推荐的模式。事件处理程序使用此模式必须快速返回,以避免阻塞Posting线程,后者可能是主线程。
MAIN 在Android上,订阅者将在Android的主线程(UI线程)中被调用。如果POST线程是在主线程中,订阅者方法将被直接调用,并阻塞Posting线程。否则事件排队等待交付(非阻塞)。使用此模式的订阅者必须快速返回以避免阻塞主线程。如果不是在Android,行为和POSTING相同。
e.g.:post(1) >onReceiveMsg(1)>post(2)>onReceiveMsg(2)>post(3)==>onReceiveMsg(3)
MAIN_ORDERED 在Android上,订阅者将在Android的主线程(UI线程)中被调用。不同于{@link #MAIN},
事件总是排队等待交付。这确保了post调用是非阻塞的。
post(1)——>post(2)——>psot(3)———>onReceiveMsg(3)
或者
post(1)——>post(2)——>psot(3)———>onReceiveMsg(2)——>onReceiveMsg(3)
BACKGROUND 在Android上,订阅者将在后台线程中被调用。如果提交线程不是主线程,则订阅者方法将在Post的线程中被直接调用。如果POST线程是主线程,EventBus使用一个单一的后台线程,它将按顺序交付所有的事件。使用此模式的订阅者应该尝试快速返回以避免阻塞后台线程。如果不是在Android,总是使用一个后台线程。
ASYNC 订阅者将在单独的线程中调用。这总是独立于发布线程和主线程。使用此模式发布事件从不等待订阅方方法。当订阅者的执行可能需要一些时间时,订阅者的方法应该使用这个Mode,例如:网络访问,请使用此模式。避免同时触发大量需要长时间运行的异步订阅者方法以此来限制并发线程的数量。EventBus使用线程池有效地重用已完成异步订阅者通知的线程。
4.2 Sticky属性: sticky是一个boolean型的参数,默认值是false,表示不启用sticky特性。正常情况下,EventBus事件传递时,我们都是先对订阅者(Subscriber)进行先注册的,然后再post事件的。当设置sticky=true时,可以先post事件,再对订阅者进行注册。
使用sticky属性时,需要在推送事件时,将post()改为postSticky().
EventBus.getDefault().postSticky(msg);
4.3 Priority属性:正常情况下,先注册的订阅者,会先收到post的事件。
然而,在设置了priority属性后,属性值越大的订阅者将更先收到事件。
1.当同一个activity中,有多个订阅者时,当ThreadMode相同时,priority越大,越早收到事件。
2.当同一个activity中,有四个订阅者时,它们的ThreadMode分别为MAIN、POSTING、BAKCKGROUND、ASYNC。
此时,发出一个Event,四个订阅者接收到事件的先后顺序:POSTING、MAIN、BAKCKGROUND、ASYNC
3.在多个activity中,且未设置priority属性或priority相同时,前面activity中的订阅者会更早接收到事件。
当设置了priority后,priority越大,越早接收到事件。
4.其余更多属性搭配条件下的情况,在应用时继续测试。
Tips: 1.获取当前线程的名字:Thread.currentThread().getName();
2.创建一个新的线程:public void testEventBus_newThread(){ new Thread( new Runnable() { @Override public void run() { Log.e("EventAc_newThread::", Thread.currentThread().getName()); EventMessage msg = new EventMessage(1,"hello eventbus"); EventBus.getDefault().post(msg); } } ).start();}
3.设置ThreadMode、Sticky、priority:@Subscribe(threadMode = ThreadMode.MAIN,sticky = true,priority = 3)public void onReceiveMsg(EventMessage message) { Log.e("MenuAc:MAIN",Thread.currentThread().getName()); Log.e("MenuAc", "onReceiveMsg: " + message.toString());}