今天看了几篇网上对EventBus的讲解,然后自己敲了即便代码,对这个EventBus也有了一点了解,下面就试着总结一下EventBus的使用。


EventBus是属于Publish/Subscribe(发布/订阅)这样的一种消息机制,用法也跟广播很像,他可以解决Fragmne之间,Activity之间,还有如网络请求成功之后回调,或者用hanler,boardcast等等办法来提醒更新ui,而且他更加的简便。


EventBus是为了方便通信的,那么通信至少得涉及到两个角色才能存在通信的问题,那么假设这里设计有两个角色:发送者(publish)与接收者(subscribe)

使用EventBus的大致使用思路:

接受者:

1:注册事件(类似广播)eventBus.register(object)

2:接收消息方法,有四种接收的方式,下面会详细说。

3:反注册eventBus.unregister(object)

发送者:

1:发送eventBus.post(object);


嗯嗯,那代码就来了:

首先说下我这个小程序的思路:MainActivity(接受者)有个按钮,直接跳转到SecondActivity(发送者)中,然后再SecondActivity中来发送消息

MainActivity:

<span style="font-family:Microsoft YaHei;">public class MainActivity extends AppCompatActivity {

    private TextView tv;
    private EventBus eventBus;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = ((TextView) findViewById(R.id.tv));
        EventBus.getDefault().register(this);
    }

    public void btnGo(View view) {
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEvent(Msg msg) {
        Log.d("bigname_log", "onEvent: 收到消息" + Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(Msg msg) {
        Log.d("bigname_log", "onEventMainThread:收到消息 " + Thread.currentThread().getName());
        tv.setText(msg.getMsg());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEventAsync(Msg msg) {
        Log.d("bigname_log", "onEventAsync: 收到消息" + Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventBackgroundThread(Msg msg) {
        Log.d("bigname_log", "onEventBackgroundThread: 收到消息" + Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void backgroundEvent(String str) {
        Log.d("bigname_log", "backgroundEvent: 收到消息" + Thread.currentThread().getName());
    }

}</span>


SecondActivity:

<span style="font-family:Microsoft YaHei;">public class SecondActivity extends AppCompatActivity {

    private EventBus eventBus;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        eventBus = EventBus.getDefault();
    }

    public void btnSendMainEvent(View view) {
        eventBus.post(new Msg("主线程消息"));
    }

    public void btnSendSubEvent(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                eventBus.post(new Msg("子线程消息"));
            }
        }).start();
    }
}
</span>


我还定义了一个类作为消息载体:

<span style="font-family:Microsoft YaHei;">public class Msg {
    private String msg;

    public Msg() {
    }

    public Msg(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}</span>


在MainActivity中你会看到有五个加了@Subscribe注释的方法,最后一个先不管,我们来看上面四个:


这里的四个方法也就是我前面所说的四种接收消息的方式,(主要是在不同线程执行的区别):


1:onEvent:消息从那个线程中发出,方法就在这个线程中执行,该方法不能执行耗时操作,否则会导致事件分发延时

2:onEventMainThread:无论消息从哪里发出,方法都在主线程中执行,比较有用哦,更新UI嘛,所以也是不能够执行耗时操作的

3:onEventBackgroundThread:这个方法一定是在子线程中执行的,如果消息从主线程中发出,那就开辟新子线程执行,如果消息从子线程中发出,那就在该子线程中执行

4:onEventAsync:这个方法也一定实在子线程中执行,但无论消息从哪发出,他都是开辟新子线程来执行。


声明不同接收方式的方法,如上所示,在@Subscribe后加上说明:

如:@Subscribe(threadMode = ThreadMode.MAIN)//对应onEventMainThread
其他同理。

上面的执行结果:

点击发送主线程消息:

onEvent: 收到消息main
 onEventAsync: 收到消息pool-1-thread-1
 onEventMainThread:收到消息 main
 onEventBackgroundThread: 收到消息pool-1-thread-2

点击发送子线程消息:
onEvent: 收到消息Thread-15735
  onEventBackgroundThread: 收到消息Thread-15735
 onEventAsync: 收到消息pool-1-thread-2
 onEventMainThread:收到消息 main

好咯,现在在来说下加@subscribe的第五个方法的作用,其实我是想说明,这些方法是通过参数来识别的而不是方法名噢,可以被多个接收到,关键是这个参数能否匹配。


还有个就是,好像以前是不用通过注释来声明这些方法的,但方法名就像上面那样不能变了,他就通过方法名来识别出是那种接收方式,但是现在大多使用注释的方式来声明那种方式,这样的方法名可以是任意的。


最后提醒一点,使用前添加依赖:

compile 'org.greenrobot:eventbus:3.0.0'