Android 开发 框架系列 EventBus 线程总线

介绍

GitHub:https://github.com/greenrobot/EventBus

先聊聊EventBus 线程总线是干什么的,使用环境,优点、缺点。

干什么的?

一句话,简单统一数据传递 和 提供主次多个线程

  • 数据传递:Android系统有很多类别的数据传递方式,例如Intent 活动之间传递数据、Message与Handler 主次线程之间传递数据、广播的方式、使用基类危险的去传递数据。传递数据的方式太多,且都需要各自的注册方式,使用使用起来比较繁琐。所以EventBus第一个用处是比较统一的去传递数据,特别是碎片、服务、活动,UI线程与子线程 之间的传递,可以有一个比较统一的方式。
  • 线程:有了数据就需要逻辑去处理它,相比android系统的数据传递后需要手动创建线程去处理逻辑后,在将得到的数据传到主线程,这一套繁复且反复的传递的过程。EventBus可以很直接的在对应线程方法里去直接互相传递处理。

使用环境

多个地方需要传递数据和相应线程逻辑处理环境,比如碎片+上下活动+服务+广播+线程的情况下,你可以想象一下为了这些数据处理需要敲不少的代码。EventBus 线程可以统一的管理,只需要在对应类里注册它。

优点

  • 简单统一数据传递
  • 清晰明了的主次线程
  • 使用class传递数据(是的,最好用的地方用一个class来传递数据,这下传一个class,就可以携带各种各样的数据了,摆脱了用Bundle传递list和数组简直太爽了)

缺点

让我研究一下它的局限性在写

使用方式:

1.添加依赖

    implementation 'org.greenrobot:eventbus:3.1.1'

2.添加注册

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

        EventBus.getDefault().register(this);//注册
       
    }

3.注销

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

4.传递数据准备,创建数据类

public class MsgData {
    private String msg;
    public MsgData(String msg){
        this.msg = msg;
    }
    public String getmsg() {
        return msg;
    }
}

5.注册发送事件与发送数据

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                EventBus.getDefault().post(new MsgData("send"));//注册,发送的是上面创建的数据class
            }
        });

 6.处理接收事件与线程

上面5个步骤都很简单,接收与线程稍微有一些需要解释:

4种线程模式:

  • POSTING:Event处理函数在发布Event的线程中执行。(ANR)
  • MAIN:Event处理函数在UI线程中执行。(ANR)
  • BACKGROUND:如果发布Event的线程是UI线程,Event处理函数就新建子线程中执行;如果发布Event的线程是子线程,那么就在当前子线程执行。(不允许修改UI)
  • ASYNC:新建子线程执行Event处理函数,新建的线程与UI线程八竿子打不着。(所以别在这里处理UI)

创建上面四种线程方法:

这些线程不是需要抽象重写或者接口的重写方法,需要自己创建一个方法,使用注释@Subscribe添加自己需要的线程模式,

下面就是创建了UI主线程方法的例子:

  @Subscribe(threadMode = ThreadMode.MAIN,sticky = false)
    public void onUiMain(MsgData msgData){
            if (msgData.getmsg().equals("send")) { //得到发送过来的数据
                mContent.setText("接收到了数据");
            }
    }

7.粘性事件

黏性事件,就是在发送事件之后再订阅该事件也能收到该事件,跟黏性广播类似。粘性事件与普通事件创建一样,只是有细微不同。

发送粘性事件:

MsgData msgData = new MsgData("我是粘性数据");
EventBus.getDefault().postSticky(msgData);//注意,这里使用的是postSticky发送粘性事件

接收粘性事件:

  @Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //重点,这里的sticky 设置为了true
    public void onUiMain(MsgData msgData){
            if (msgData.getmsg().equals("我是粘性数据")) { 
                mContent.setText("接收粘性数据");
            }
    }

粘性事件会一直保存在内存中,等待后续的接收粘性事件方法的创建与接收,因为会一直停留在内存里,所以我们需要去清理粘性事件,粘性事件接收到了确定无用后就清理是个好习惯。

  • 移除指定的粘性事件:removeStickyEvent(Object event);
  • 移除指定类型的粘性事件:removeStickyEvent(Class<T> eventType);
  •  移除所有的粘性事件:removeAllStickyEvents();
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void onUiMain(MsgData msgData){
            if (msgData.getmsg().equals("粘性数据")) {
                mContent.setText("接收到了数据");
            }
            if(EventBus.getDefault().removeStickyEvent(msgData)){
                Toast.makeText(this,"清理粘性事件成功",Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(this,"清理粘性事件失败",Toast.LENGTH_SHORT).show();
            }
    }

猜你喜欢

转载自blog.csdn.net/qq_37217804/article/details/82118675