EventBus 3.0使用详解源码分析(一)

目录

 

 Eventbus前言

 EventBus简介

 EventBus使用


  •  Eventbus前言

        在项目开发中,总会遇到组件和组件之间,组件和线程、service之间进行通信,比如activity和多个fragment通信。android 原生也提供了一下方法,我们经常用的,有广播,handler,写回调方法以及intent。这些都可以解决通信需求,但是这样耦合度比较高,并且代码量也比较大。今天介绍的eventbus可以很方便的解决这些问题。

  •  EventBus简介

         首先容许我盗一张图:

          大致意思是说,eventbus能够简化组件间通信,代码更简单,有效分离了时间发送方和接收方,并且有很多应用集成了eventbus安全和性能应该有保障。

           最后单独说一下他的基本原理: eventbus就是一个典型的观察者模式的使用,通过publisher发布消息,然后Subscriber接收消息。然后进行处理。整个结构大致有三个模块需要注意:

  •             1 event:发布者发布的消息,可以是继承自Object的任意类。
  •             2 publisher:事件的发布者,可以在任意线程发布消息,一般通过EventBus.getDefault().post(Event)就可以发布。
  •             3 Subscriber:  事件的接收者,通过register,unregister函数来注册成为观察者。处理事件的方法要通过注解@Subscribe()中的参数来标明处理事件的线程模型,优先权,以及是否是黏性广播。

           在观察者类中处理消息的函数要通过注解@Subscribe(ThreadMode,isSticky,priority)来指定处理消息的一些基本信息,注解共有三个参数。其中ThreadMode表示在哪个线程里面处理收到的消息,它有四种方式:     

  •              1 POSTING, 默认参数,哪个线程发布的消息,就在哪个线程里面处理消息。
  •              2 MAIN, 表示在主线程处理消息,就是ui线程,不能进行耗时操作。
  •             3 BACKGROUND, 表示后台线程处理,不能进行ui操作,如果发布消息在ui线程中发布,那会重启一个线程,如果是后台线程,就在发布消息的线程处理。
  •             4 ASYNC ,无论发布线程是哪个,都会重新开一个线程处理。可以进行耗时操作。

             sticky 这个参数表示是否是黏性广播,默认false,非黏性广播当发布者发布消息的时候,没有注册的开发者不能收到任何消息,如果注册为黏性,那么当观察者注册成功之后,会收到最后一条发布的广播。

             priority表示处理的优先级。默认为0.

  •  EventBus使用

         首先添加依赖:

implementation 'org.greenrobot:eventbus:3.1.1'

         简单写一个消息类:

public class MessageEvent extends MessageObject{

    String message;

    int id;

    public MessageEvent(String msg,int id){
        super(msg);
        this.message = msg;
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

  eventbus可以用于activity,fragment,service等控件,其注册方式都一样,本文用activity做例子,发送消息的activity如下:

public class MainActivity extends Activity {

    @BindView(R.id.mainclick)
    Button mainClick;

    @BindView(R.id.threadclick)
    Button threadClick;

    WidgetBroadcastReceiver mReceiver;

    RxPermissions rxPermissions;

    @SuppressLint("HandlerLeak")
    Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    postMsgMain();
                    postMsgThread();
                    break;
                default:
                    break;
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mReceiver = new WidgetBroadcastReceiver();
        ButterKnife.bind(this);
        mainClick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent ii = new Intent(MainActivity.this, EventBusActivity.class);
                startActivity(ii);
                mHandler.sendEmptyMessageDelayed(1, 1000 * 5);

            }
        });

    }

    private void postMsgMain(){
        EventBus.getDefault().post(new MessageObject("this is default"));
        Log.e("tag"," ****main id===="+Thread.currentThread().getId());
    }

    private void postMsgThread() {
       new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new MessageEvent("from thread",1 ));
                Log.e("tag","*thread id===="+Thread.currentThread().getId());
            }
        }).start();

    }

}

点击按钮延后5,6秒通过EventBus.getDefault().post()分别发送一个主线程消息和后台消息。

public class EventBusActivity extends Activity {

    @BindView(R.id.content_text)
    TextView contentView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_bus);
        ButterKnife.bind(this);
        //注册观察者
        EventBus.getDefault().register(this);
    }


    /**
     * 处理消息,只能是一个参数,通过参数识别处理哪个消息。发送的消息和参数匹配才会处理。
     * @param me
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageObject me) {
        String content = me.getObject();
        contentView.setText(content);
        Log.e("tag", "the MAIN msg id==="+Thread.currentThread().getId());
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessageEvent1(MessageEvent me) {
        String content = me.getMessage();
        Log.e("tag", "the POSTING msg===" + me.getMessage()+Thread.currentThread().getId());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessageEvent2(MessageEvent me) {
        String content = me.getMessage();
        Log.e("tag", "the BACKGROUND msg===" + me.getMessage()+Thread.currentThread().getId());
    }
    
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessageEvent3(MessageEvent me) {
        String content = me.getMessage();
        Log.e("tag", "the ASYNC msg===" + me.getMessage()+Thread.currentThread().getId());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(EventBus.getDefault().isRegistered(this)) {
            //取消注册
            EventBus.getDefault().unregister(this);
        }
    }
}

在这里接收处理消息。在这个例子中通过打印线程id确认执行属性。日志如下:

 EventBus的基本用法就是这样,接下来我会分析源码来解释eventbus的运行机制。

 EventBus的github地址:

 eventbus源码

猜你喜欢

转载自blog.csdn.net/alvinhuai/article/details/81474599