EventBus基础教程解析,一分钟学会EventBus的使用

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

近段时间有幸接触EventBus这个不错的Android通信框架,确实在实际开发中方便了不少。以前我们子线程与主线程、Fragment、Service之间的通信需要通过Handler来实现通信,现在我们只需要通过EventBus就可以很方便完成我们的需求。

EventBus源码下载地址:github.com/greenrobot/…

一、概述

EventBus是一款针对Android的publish/subscribe(发布 / 订阅)消息事件总线,它简化了组件之间的通信,使我们的应用程序更加简单、通信更加快捷。我们来看EventBus的消息传递图:

eventBus

EventBus事件主线由四大部分组成:

  • Publisher发布者:用于分发我们的Event事件,在EventBus中通过post方法进行分发传送。
  • Subscriber订阅者:用于接受我们的事件,我们在订阅事件中处理我们接收的数据。订阅事件有四种,都是以onEvent开发。
  • Event事件:任何一个对应都可以作为事件,比如任何字符串,事件是发布者和订阅者之间的通信载体。
  • EventBus:类似于中转站,将我们的事件进行对应的分发处理。

举个通俗点的例子,EventBus消息机制就是我们生活中的寄快递,你去快递站点寄快递,你就是事件发送者,你的包裹就是事件,快递站点就是EventBus,接收快递的人就是事件订阅者。快递公司经过装车分类最后把你的快递寄到收件人手里,就类似EventBus最后将事件成功传达。

二、Subscriber的ThreadMode

EventBus中的Subscriber有四种订阅函数。

  • onEvent:使用onEvent作为订阅函数,则事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
  • onEventMainThread:使用onEventMainThread作为订阅函数,则不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作,不然引起ANR异常。
  • onEventBackground:使用onEventBackgrond作为订阅函数,如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
  • onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.

分析以上四种ThreadMode,我们可以明显发现上面四种类型就是为了解决我们的组件之间通信,举个例子,以往我们开启一个子线程进行download,然后通过Hanlder进行发布消息在UI线程中更新我们的UI组件。、

二、EventBus的使用步骤

前戏: Android Studio用户在对应module的gradle中添加:

compile 'de.greenrobot:eventbus:2.4.0'
复制代码

Eclipse用户直接将jar包拷贝到libs目录下即可。

扫描二维码关注公众号,回复: 13281184 查看本文章

1、定义事件,我们前面说过事件可以是任何实体对象,只要它能满足我们的传递数据的需要,同时要保证它的唯一性,不然如果有多个事件发送相同的事件类型,会导致我们接收方错乱,所以一般我们都是自定义一个事件类进行封装处理我们的数据。例如下面:

	    public static class EventText{
	        private String text;
	        public EventText(String text){
	            this.text = text;
	        }
	
	        public String getText(){
	            return this.text;
	        }
    	}
复制代码

我们定义一个EventText事件(说白了就是一个类),里面封装了我们的数据。

2、发送事件,事件已经定义完毕,我们就可以进行发送事件,来传递我们的数据。

 EventBus.getDefault().post(new EventText(response));
复制代码

3、事件订阅者页面的初始化工作,在EventBus中要求事件的接受页面需要进行register,同时在页面销毁时进行反注册unregister。 一般,我们在Activity的onCreate()方法中进行注册:

	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
    }
复制代码

在onDestroy()方法中进行反注册:

	protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
复制代码

4、事件订阅者的进行数据处理,事件携带者我们的数据发送过来,现在我们需要对事件进行处理。前面我们已经说了EventBus中定义了四种ThreadMode的事件处理,所以我们根据我们的需要进行一种接收处理即可。例如:

	public void onEvent(EventText eventText){
        tv_textTextView.setText(eventText.getText());
    }
复制代码

这就是EventBus的最基本使用步骤,我们先来概括性的总结几个方法:

  • EventBus.getDefault().register(Object subscriber):注册EventBus
  • EventBus.getDefault().unregister(Object subscriber):反注册EventBus
  • EventBus.getDefault().post(Object event):发送消息事件
  • public void onEvent*****(Object event):消息接收处理
  • EventBus.getDefault().registerSticky(Object subscriber):粘性EventBus注册,用在此种情况消息先发送,后注册订阅者,如果使用register,会导致我们接收不到消息。
  • EventBus.getDefault().postSticky(Object event):无订阅者时发送消息,又希望有订阅者时能接收到该消息时使用。

下面我们就在Android Studio中演示一把怎么使用的。我写了几个实例demo,效果图如下:

效果图

在上面的效果图中,我写了三个demo,一个是在activity内部进行数据传递,第二个是从别的activity进行获取数据,第三个是activity向别的页面传递数据。三个demo中分别对应:

  • 第一个是该页面作为消息的发送和订阅者,全部在本身。
  • 第二个是页面作为事件的订阅者,别的页面作为事件发送者
  • 第三个是页面作为事假发送者,别的页面作为事件订阅者。此时先有发送者后有订阅者,会用到postSticky、registerSticky。

我们就挑第一个demo给大家展示,有兴趣的可以下载demo看看。

1、先定义我们的消息事件,用于封装我们传递的数据。

	public static class FirstEvent{
        private String value;

        public FirstEvent(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

    }
复制代码

2、代码比较简单,我们直接看下全部页面代码。

	public class FirstActivity extends Activity {
	    private Button btn_showDownLoad;
	    @Override
	    protected void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        EventBus.getDefault().register(this);
	        setContentView(R.layout.activity_first);
	        btn_showDownLoad = (Button) findViewById(R.id.btn_toast);
	        btn_showDownLoad.setOnClickListener(new View.OnClickListener() {
	            @Override
	            public void onClick(View v) {
	                new Thread(new Runnable() {
	                    @Override
	                    public void run() {
	                        try {
	                            Thread.sleep(1000);
	                        } catch (InterruptedException e) {
	                            e.printStackTrace();
	                        }
	                        EventBus.getDefault().post(new EventBusEvents.FirstEvent("我是从网络下载的文本"));
	                    }
	                }).start();
	            }
	        });
	    }
	
	    @Override
	    protected void onDestroy() {
	        super.onDestroy();
	        EventBus.getDefault().unregister(this);
	    }
	
	    public void onEventMainThread(EventBusEvents.FirstEvent firstEvent){
	        Toast.makeText(this, firstEvent.getValue(),Toast.LENGTH_SHORT).show();
	    }
	}
复制代码

我们在onCreate()方法中进行注册EventBus事件,在onDestroy()方法中销毁EventBus事件,然后点击Button按钮进行发送Event事件,同时开启一个子线程模拟,最后定义我们的事件接收函数。简单的逻辑就是这样子,很方便。

通过上面的实例发现,我们传递数据确实方便很多,也不需要使用Intent进行数据的传递,EventBus在一些特殊情况下,确实给我们提供了很大的方便,但是我们也要视情况而定,不然会导致过多的Event事件,也不是很好。

源码下载地址

猜你喜欢

转载自juejin.im/post/7032802909972594702