EventBus的使用

一、简介

EventBus是一款本地组件间通信框架

组件间通信框架star量第一:14.8k,在大型项目的Activities,fragments,Threads,Services都可以看到它的使用场景,尽管EventBus在向未创建的组件传递事件时有些局限,仅适合在“活着的”组件间传递消息,但仍不妨碍它活跃在各个大型项目各个场景里。

  • 官网地址:http://greenrobot.org/eventbus/documentation/how-to-get-started/

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

1.1 三个角色

  1. Event:事件,它可以是任意类型,EventBus会根据事件类型进行全局的通知。
  2. Subscriber:事件订阅者,在EventBus 3.0之前我们必须定义以onEvent开头的那几个方法,分别是onEventonEventMainThreadonEventBackgroundThreadonEventAsync,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe,并且指定线程模型,默认是POSTING
  3. Publisher:事件的发布者,可以在任意线程里发布事件。一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。

1.2 四种线程模型

EventBus3.0有四种线程模型,分别是:

  1. POSTING:默认,表示事件处理函数的线程跟发布事件的线程在同一个线程。
  2. MAIN:表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
  3. BACKGROUND:表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
  4. ASYNC:表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

二、EventBus的基本用法:

2.1添加依赖:

implementation 'org.greenrobot:eventbus:3.1.1'

如果要使用索引 还需添加

defaultConfig {
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ]
        }
    }
}
dependencies {
...
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}

2.2如何使用:

1.首先定义一个数据类用于EventBus数据间的通信

eg:

public class MessageEvent{
    private String message;

    public MessageEvent() {
    }

    public  MessageEvent(String message){
        this.message=message;
    }

    public String getMessage() {
        return message;
    }

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

    @Override
    public String toString() {
        return "MessageEvent{" +
                "message='" + message + '\'' +
                '}';
    }
}

2.在activity中注册事件

EventBus.getDefault().register(this);

3.使用普通方式接收信息(注意: 注解的方法  必须是   public

不是public 可能引发:its super classes have no public methods with the @Subscribe annotation  错误

@Subscribe(threadMode = ThreadMode.MAIN)
    public void Event(MessageEvent messageEvent) {
        Log.d("tgw2", "Event:非粘性事件 "+messageEvent.toString());
        tvEvent.setText(messageEvent.getMessage());
    }

4.非粘性事件发送消息注意发送的必须与上面订阅的  ---Event方法中的参数一致

MessageEvent messageEvent = new MessageEvent();
messageEvent.setMessage(editText.getText().toString());
EventBus.getDefault().post(messageEvent);

5.完整例子

  1. 首先在oncreated()方法中注册
  2. 通过点击事件开启一个新的Activity---SecondActivity
  3. 在SecondActivity通过点击事件使用 EventBus.getDefault().post(messageEvent); 发送消息 返回MainActivity
  4. 在MainActivity中的 onDestroy() 方法中 将 EventBus  注销

 

public class MainActivity extends AppCompatActivity {

    private Button btEventBus;
    private Button btStick;
    private TextView tvEvent;

    private boolean isStart = true;


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

        btEventBus = findViewById(R.id.bt_eventbus);
        tvEvent = findViewById(R.id.tv_event);
        btStick = findViewById(R.id.bt_stick);

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

        //跳转另一个活动 给当前页面的tvEvent赋值
        btEventBus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
                
            }
        });


       
    }

   
    

    //非粘性事件
    @Subscribe(threadMode = ThreadMode.MAIN)
        public void Event(MessageEvent messageEvent) {
        Log.d("tgw2", "Event:非粘性事件 "+messageEvent.toString());
        tvEvent.setText(messageEvent.getMessage());
    }

   

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

        //粘性事件取消注册
        MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
        // Better check that an event was actually posted before
        if (stickyEvent != null) {
            // "Consume" the sticky event
            EventBus.getDefault().removeStickyEvent(stickyEvent);
            // Now do something with it
        }
    }

SecondActivity:

public class SecondActivity extends AppCompatActivity {

    private Button btReturn;
    private EditText editText;

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

        btReturn = findViewById(R.id.bt_eventbus);
        editText = findViewById(R.id.edit_event);

        btReturn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                MessageEvent messageEvent = new MessageEvent();
                messageEvent.setMessage(editText.getText().toString());

                Log.d("tgw", "onClick: " + messageEvent.getMessage() );
                //注意返回的值必须是类对象
                //1.非粘性事件  发送的值将会在MainActivity中获取到 
                EventBus.getDefault().post(messageEvent);
           
                finish();
            }
        });
    }
}

 

2.3使用粘性事件

1.它的特点就是可以获取上一次发送的消息  (能够收到订阅之前发送的消息就是不在oncreated方法中注册通过button点击事件控制注册事件)

异同点:

非粘性---

之前我们需要先注册  在发送消息 这样才可以接收(不然就算你先发送  在注册  也需要再次发送才可以接收)

粘性---

我们可以先使用

EventBus.getDefault().postSticky(new MessageEvent("粘性"));

发送消息,在通过

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class); String stick = stickyEvent.getMessage();

接收消息 但是此时我们还收不到消息 之后还需注册:

EventBus.getDefault().register(MainActivity.this);

这样就得到的信息

 

2.粘性  使用  sticky = true  参数   至于 priority = 2  适用于定义优先级  类似广播的

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN,priority = 2)

使用方法 :我们 先点击 btEventBus 中的事件  再点击 btStick 中的点击事件  就可以接收到信息了

粘性注销 在onDestroy()中

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if (stickyEvent != null) {
    // "Consume" the sticky event
    EventBus.getDefault().removeStickyEvent(stickyEvent);
    // Now do something with it
}

 

3.优先级

关注 Event(MessageEvent messageEvent)   和  EventPriority(MessageEvent messageEvent) 方法

我在EventPriority(MessageEvent messageEvent)  方法中使用了   EventBus.getDefault().cancelEventDelivery(messageEvent);

方法用于 消息截断 

 

完整代码:

public class MainActivity extends AppCompatActivity {

    private Button btEventBus;
    private Button btStick;
    private TextView tvEvent;

    private boolean isStart = true;


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

        btEventBus = findViewById(R.id.bt_eventbus);
        tvEvent = findViewById(R.id.tv_event);
        btStick = findViewById(R.id.bt_stick);

    
            
         //发送粘性事件
         btEventBus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {                        
                EventBus.getDefault().postSticky(new MessageEvent("粘性"));
            }
        });

        //注册粘性
        btStick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isStart) {
                    EventBus.getDefault().register(MainActivity.this);
                    isStart = false;
                }
            }
        });


        
    }

    //粘性事件 能够收到订阅之前发送的消息(就是不在oncreated方法中注册通过button点击事件控制注        册事件)
    //注意返回的值必须是类对象
    //接受从SecondActivity返回的值
    @Subscribe(sticky = true, threadMode = ThreadMode.MAIN,priority = 1)
    public void Event(MessageEvent messageEvent) {

        MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
        String stick = stickyEvent.getMessage();
        Log.d("tgw2", "Event:粘性事件优先级低 " + messageEvent.toString() + "---" + stick);

        tvEvent.setText(messageEvent.getMessage());
    }

    //优先级threadMode  参数值要一样(意思是订阅方法是一样的)
    @Subscribe(sticky = true, threadMode = ThreadMode.MAIN,priority = 2)
    public void EventPriority(MessageEvent messageEvent) {

        MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
        String stick = stickyEvent.getMessage();
        Log.d("tgw2", "Event:粘性事件优先级高 " + messageEvent.toString() + "---" + stick);

        tvEvent.setText(messageEvent.getMessage());
        // 终止事件的继续分发(感觉无用)
        EventBus.getDefault().cancelEventDelivery(messageEvent);
    }

    

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

        MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
        // Better check that an event was actually posted before
        if (stickyEvent != null) {
            // "Consume" the sticky event
            EventBus.getDefault().removeStickyEvent(stickyEvent);
            // Now do something with it
        }
    }

 

参考:

https://www.jianshu.com/p/25388d6446bf

https://www.jianshu.com/p/f9ae5691e1bb

https://www.jianshu.com/p/e7d5c7bda783

 

 

 

 

 



 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值