欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-09 23:33:27
...

目录

 

 Eventbus前言

 EventBus简介

 EventBus使用


  •  Eventbus前言

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

  •  EventBus简介

         首先容许我盗一张图:

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

          大致意思是说,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'

         如果需要混淆要添加一下代码:

         

-keepattributes *Annotation*
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
 
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

       简单写一个消息类:

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 3.0使用详解源码分析(一)

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

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

 EventBus的github地址:

 eventbus源码