EventBus是使用十分广泛的事件总线框架, 2.0到3.0的变化还是挺大的,使用方式
点击OK即可。
3.0与2.x的区别
主要区别在订阅函数的不同
EventBus2.x中只暴露了四个方法供用户调用,分别是- onEvent:该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
- onEventMainThread:不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
- onEventBackgroundThread:如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
- onEventAsync:无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.EventBus3.0中必须使用注解,例如:
//一定创建子线程 @Subscribe(threadMode = ThreadMode.Async,sticky = true,priority = 100) public void onReceive(FirstEvent event){ Log.e(TAG, "Async: "+Thread.currentThread()+event.getMsg() ); } //如果是事件从子线程发出,订阅函数就执行在那个子线程,不会创建新的子线程;如果主线程发出事件,则创建子线程。 @Subscribe(threadMode = ThreadMode.BackgroundThread,sticky = false,priority = 100) public void onReceive2(FirstEvent event){ Log.e(TAG, "BackgroundThread: "+Thread.currentThread()+event.getMsg() ); } //订阅函数一定执行在主线程 @Subscribe(threadMode = ThreadMode.MainThread,sticky = true,priority = 100) public void onReceive3(FirstEvent event){ Log.e(TAG, "MainThread: "+Thread.currentThread()+event.getMsg() ); } //事件发送者在哪个线程就执行在哪个线程 @Subscribe(threadMode = ThreadMode.PostThread,sticky = true,priority = 100) public void onReceive4(FirstEvent event){ Log.e(TAG, "PostThread: "+Thread.currentThread()+event.getMsg() ); }
好处在于订阅函数可以随便起名字,其他与2.x没什么不同。这里Subscribe中的key需要解释一下含义,Subscribe中可以传三种值: -
ThreadMode:这是个枚举,有四个值,决定订阅函数在哪个线程执行
- PostThread:事件发送者在哪个线程就执行在哪个线程。同2.x中的onEvent方法,默认值就是这个
- MainThread:订阅函数一定执行在主线程。同onEventMainThread方法
- BackgroundThread:如果是事件从子线程发出,订阅函数就执行在那个子线程,不会创建新的子线程;如果主线程发出事件,则创建子线程。同onEventBackgroundThread方法
- Async:一定创建子线程。同onEventAsync方法。
-
sticky:默认为false,如果为true,当通过
postSticky
发送一个事件时,这个类型的事件的最后一次事件会被缓存起来,当有订阅者注册时,会把之前缓存起来的这个事件直接发送给它。使用在比如事件发送者先启动了,订阅者还没启动的情况。
- priority:默认值为0。订阅了同一个事件的订阅函数,在ThreadMode值相同的前提下,收到事件的优先级。
具体使用 注意:sticky属性的详细使用请看我的下一篇博客。
创建事件:
public class FirstEvent { private String msg; public FirstEvent(String msg){ this.msg = msg; } public String getMsg(){ return msg; } }
在MainActivity的onCreate方法中注册,onDestroy方法中反注册
实例:EventBus.getDefault().register(this); EventBus.getDefault().unregister(this);
首先在MainActivy里写一个按钮,跳转到MainActivity2中,在MainActivity2中写三个按钮来发送事件。
2.MainActivity2里的代码public class MainActivity extends Activity { private Button btn; private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); EventBus.getDefault().register(this); // EventBus.getDefault().getStickyEvent(FirstEvent.class);//来获取这些缓存事件。 btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this,MainActivity2.class)); } }); } //一定创建子线程 @Subscribe(threadMode = ThreadMode.Async,sticky = true,priority = 100) public void onReceive(FirstEvent event){ Log.e(TAG, "Async: "+Thread.currentThread()+event.getMsg() ); } //如果是事件从子线程发出,订阅函数就执行在那个子线程,不会创建新的子线程;如果主线程发出事件,则创建子线程。 @Subscribe(threadMode = ThreadMode.BackgroundThread,sticky = false,priority = 100) public void onReceive2(FirstEvent event){ Log.e(TAG, "BackgroundThread: "+Thread.currentThread()+event.getMsg() ); } //订阅函数一定执行在主线程 @Subscribe(threadMode = ThreadMode.MainThread,sticky = true,priority = 100) public void onReceive3(SecondEvent event){ Log.e(TAG, "MainThread: "+Thread.currentThread()+event.getMsg() ); } //事件发送者在哪个线程就执行在哪个线程 @Subscribe(threadMode = ThreadMode.PostThread,sticky = true,priority = 100) public void onReceive4(ThirdEvent event){ Log.e(TAG, "PostThread: "+Thread.currentThread()+event.getMsg() ); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } }
public class MainActivity2 extends Activity implements View.OnClickListener{ private Button onebtn; private Button twobtn; private Button threebtn; private static final String TAG = "MainActivity2"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); onebtn = (Button) findViewById(R.id.one); twobtn = (Button) findViewById(R.id.two); threebtn = (Button) findViewById(R.id.three); onebtn.setOnClickListener(this); twobtn.setOnClickListener(this); threebtn.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.one: // new Thread(new Runnable() { // @Override // public void run() { // EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked")); // } // }).start(); EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked")); break; case R.id.two: EventBus.getDefault().post(new SecondEvent("SecondEvent btn clicked")); break; case R.id.three: EventBus.getDefault().post(new ThirdEvent("ThirdEvent btn clicked")); break; } } }
当点击第一个按钮时,log输出日志
07-07 16:00:22.906 14769-15446/com.hhj.qiyuan E/MainActivity: Async: Thread[pool-2-thread-1,5,main]FirstEvent btn clicked
07-07 16:00:22.906 14769-15447/com.hhj.qiyuan E/MainActivity: BackgroundThread: Thread[pool-2-thread-2,5,main]FirstEvent btn clicked可以看到,在发送FirstEvent时,在MainActiviy中虽然有四个函数,但只有第一个和第二个函数的接收参数是FirstEvent,所以会传到它这来接收。所以这里识别调用EventBus中四个函数中哪个函数,是通过参数中的实例来决定的。
好了想了解sticky用法的朋友可以到我下一篇博客观看。