EventBus3.0的使用

一、添加依赖: compile ‘org.greenrobot:eventbus:3.0.0’

二、先看一个小demo

MainActivity

布局文件太过于简单就不贴出来了,就是一个TextView一个Button;
这里实现功能就是Button一个点击跳转到SecendActivity界面;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EventBus.getDefault().register(this);

        tv = (TextView) findViewById(R.id.tv);
        btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,SecendActivity.class);
                startActivity(intent);
            }
        });
    }

@Subscribe(threadMode = ThreadMode.MAIN)
    public void onShowMessageEvent(MessageEvent messageEvent){
        tv.setText("Message From ActivityB :"+messageEvent.getMessage());
    }

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

SecendActivity:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_secend);
        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MessageEvent("ni hao FirstActivity"));
                SecendActivity.this.finish();
            }
        });
    }

MessageEvent:

public class MessageEvent {

    private String message;

    public MessageEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

这里的逻辑也是一目了然:SecendActivity中也有且只有一个Button用来点击触发: EventBus.getDefault().post(new MessageEvent(“ni hao FirstActivity”));这行代码的逻辑;

这里简单解释一下就是:这行代码发送了一个MessageEvent对象,因为我们添加了依赖,并且在MainActivity中注册EventBus的,最最关键的是我们声明了方法:onShowMessageEvent()这个方法的参数就是一个MessageEvent,会根据合适的事件参数来匹配相应的方法;

三、注解中的线程模型

在EventBus的事件处理函数中需要指定线程模型,即指定事件处理函数运行所在的想线程。在上面我们已经接触到了EventBus的四种线程模型。那他们有什么区别呢?在EventBus中的观察者通常有四种线程模型,分别是PostThread(默认)、MainThread、BackgroundThread与Async。

首先解释一下什么是发布事件:EventBus.getDefault().post();方法所执行的地方叫做发布事件的地方;

  • PostThread:如果使用事件处理函数指定了线程模型为PostThread,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为PostThread的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。

  • MainThread:如果使用事件处理函数指定了线程模型为MainThread,那么不论事件是在哪个线程中发布出来的,该事件处理函数都会在UI线程中执行。该方法可以用来更新UI,但是不能处理耗时操作。

  • BackgroundThread:如果使用事件处理函数指定了线程模型为BackgroundThread,那么如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。

  • Async:如果使用事件处理函数指定了线程模型为Async,那么无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行。同样,此事件处理函数中禁止进行UI更新操作。

四、粘性事件

粘性事件就是A需要通过post发布消息,这个消息需要B处理即注册了EventBus事件的地方,但是在A发送消息的时候B并没有注册该事件的处理,粘性事件的意思就是在这种情况下,B再注册事件之后马上就能收到A之前已经发送过来的消息,但是也有限制:

  • 只能接收到一个
  • 这个事件是最近发布的那个事件

    用法:
    订阅粘性事件:

EventBus.getDefault().register(Activity.this);

粘性事件处理方法:

@Subscribe(sticky = true)
public void XXX(MessageEvent messageEvent) {
    ......
}

发送粘性事件:

EventBus.getDefault().postSticky(new MessageEvent("test"));

例子:

public class StickyModeActivity extends AppCompatActivity {

    int index = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sticky_mode);
        findViewById(R.id.post).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().postSticky(new MessageEvent("test" + index++));
            }
        });
        findViewById(R.id.regist).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().registerSticky(StickyModeActivity.this);
            }
        });

        findViewById(R.id.unregist).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().unregister(StickyModeActivity.this);
            }
        });

    }


    @Subscribe(threadMode = ThreadMode.MainThread, sticky = true)
    public void onMessageEventMainThread(MessageEvent messageEvent) {
        Log.e("MainThread", messageEvent.getMessage());
    }

}

以上代码中有三个按钮 控制按钮的点击事件的顺序就可以得到想要的效果;

小结

简单学习了一下EventBus的使用方法,感觉接口回调,广播接收器,各有各的使用场景吧,不过使用起来还是很方便快捷的,而且使用的地方也很广泛,最大的好处还是不用我们考虑主线程和子线程中UI、网络访问等等复杂的问题,一个注解就能解决;

注册EventBus的Activity就像是一个订阅者订阅了某个事件——事件作为参数由处理事件方法处理该事件(像是观察者),事件发生的地方会很多——post事件的地方(就像是被观察者);

希望能慢慢摸索EventBus更多的原理性的东西,更更加复杂确不失灵活的使用的方法!

参考博客地址:https://segmentfault.com/a/1190000004276926

最后感谢各种无私奉献的人!

你可能感兴趣的:(android)