EventBus使用之基础

    xiaoxiao2022-06-28  40

    开源项目链接

    EventBus项目:https://github.com/greenrobot/EventBus EventBusDemo下载:https://github.com/yanbober/Android-Blog-Source/tree/master/Android-EventBus-Demo

    背景介绍

    如果你学习过设计模式,那么当想通知其他组件某些事情发生时你一定会使用观察者模式。好了,既然能想到这个设计模式,那么就来看一个屌爆天的Android开源框架EventBus。主要功能是替代Intent、Handler、BroadCast在Fragment、Activity、Service、线程之间传递消息。他的最牛逼优点是开销小,代码简洁,解耦代码。

    基础介绍

    上面说了,EventBus是一个观察者模式的实现,既然这样,那他就有如下三个要素:

    Event:事件Subscriber:事件订阅者,接收特定的事件。Publisher:事件发布者,用于通知Subscriber有事件发生。

    其中,Event可以使任意类型对象。Subscriber都是以约定的onEvent开头的函数,具体是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync这四个。Publisher可以通过post(Object)在任意线程任意位置发送事件。

    官方这个图就很直观的说明了这种观察者模式的架构:

    依据开源库组件的说明文档来操作:

    在工程gradle中添加:compile ‘de.greenrobot:eventbus:2.4.0’。按照文档HOWTO.md进行操作。

    Subscriber以onEvent开头的4个函数区别:

    onEvent:事件的处理在和事件的发送在相同的线程,所以事件处理时间不应太长,不然影响事件的发送线程。onEventMainThread: 事件的处理会在UI线程中执行。事件处理时间不能太长,长了会出现臭名远之的ANR。onEventBackgroundThread:事件的处理会在一个后台线程中执行。虽然名字是BackgroundThread,事件处理是在后台线程,但事件处理时间还是不应该太长,因为如果发送事件的线程是后台线程,会直接在当前后台线程执行事件;如果当前线程是UI线程,事件会被加到一个队列中,由一个线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。onEventAsync:事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程,但最好限制线程的数目。

    下面还是先上代码再总结分析。

    实战一把屌爆天的功能

    如下示例演示了EventBus的线程间通信与线程内通信及自定义消息结构的通信。

    下载该实例工程完整代码点击我

    如下是主界面显示效果:

    接着看代码:

    首先自定义一个消息数据类型,如下:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class MsgBean {      private String msg;        public MsgBean(String msg) {          this .msg = msg;      }        public String getMsg() {          return msg;      }        public void setMsg(String msg) {          this .msg = msg;      } }

    接着编写主界面及逻辑代码:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 public class MainActivity  extends AppCompatActivity  implements View.OnClickListener {      private TextView mShowInfo1, mShowInfo2, mShowInfo21, mShowInfo22;      private Button mBtn1, mBtn2, mBtn21, mBtn22;        private int mCount =  0 ;        @Override      protected void onCreate(Bundle savedInstanceState) {          super .onCreate(savedInstanceState);          setContentView(R.layout.activity_main);            initData();      }        private void initData() {          mShowInfo1 = (TextView) findViewById(R.id.first_show);          mBtn1 = (Button) findViewById(R.id.get_btn_1);          mBtn1.setOnClickListener( this );            mShowInfo2 = (TextView) findViewById(R.id.second_show);          mBtn2 = (Button) findViewById(R.id.get_btn_2);          mBtn2.setOnClickListener( this );            mShowInfo21 = (TextView) findViewById(R.id.first_show_lin2);          mBtn21 = (Button) findViewById(R.id.get_btn_1_line2);          mBtn21.setOnClickListener( this );            mShowInfo22 = (TextView) findViewById(R.id.second_show_line2);          mBtn22 = (Button) findViewById(R.id.get_btn_2_line2);          mBtn22.setOnClickListener( this );      }        @Override      protected void onStart() {          super .onStart();          //注册EventBus          EventBus.getDefault().register( this );      }        @Override      protected void onStop() {          super .onStop();          //取消EventBus          EventBus.getDefault().unregister( this );      }        //事件1接收者:在主线程接收      public void onEvent(String event){          mShowInfo1.setText(event);      }      //事件2接收者:在主线程接收自定义MsgBean消息      public void onEvent(MsgBean event){          mShowInfo21.setText(event.getMsg());      }      //事件3接收者:在主线程接收      public void onEventMainThread(Integer event) {          mShowInfo2.setText(event+ "" );      }        @Override      public void onClick(View v) {          switch (v.getId()) {              case R.id.get_btn_1:                  //事件1发送者:在主线程发送                  EventBus.getDefault().post( "test!" );                  break ;              case R.id.get_btn_1_line2:                  //事件2发送者:在主线程发送自定义MsgBean消息                  EventBus.getDefault().post( new MsgBean( "type" ));                  break ;              case R.id.get_btn_2:                  //事件3发送者:在子线程循环发送                  new Timer().schedule( new TimerTask() {                      @Override                      public void run() {                          EventBus.getDefault().post(mCount);                          if (mCount >=  3 ) {                              this .cancel();                              mCount =  0 ;                          }                          mCount++;                      }                  },  0 ,  1000 );                  break ;          }      } }

    xml代码太简单就省略了。

    如下运行结果:

    下载该实例工程完整代码点击我

    从上面代码可以看见,当发过来一个消息的时候,EventBus区分onEventxxx被调运通过发送消息的参数类型区分(如:post(new MsgBean(“type”))对应onEvent(MsgBean event),post(“test!”)对应onEvent(String event))。

    总结

    通过上面基础实战发现,使用EventBus的基本步骤就是如下4步:

    定义事件类型(或者不定义)。例如:MsgBean等定义事件处理方法。例如:onEvent等注册订阅者。例如:EventBus.getDefault().register(this)发送事件。例如:EventBus.getDefault().post(new MyEvent())
    转载请注明原文地址: https://ju.6miu.com/read-1124320.html

    最新回复(0)