美文网首页
EventBus使用详解

EventBus使用详解

作者: Bfmall | 来源:发表于2023-07-20 12:40 被阅读0次

一、EventBus的使用介绍
EventBus简介
EventBus是一个开源库,由GreenRobot开发而来,是用于Android开发的 “事件发布—订阅总线”, 用来进行模块间通信、解藕。它可以使用很少的代码,来实现多组件之间的通信。
Android系统内置的事件通讯存在缺点:
Android系统中的事件通信则是 handler (消息机制) 和 BroadCastReceiver (广播机制), 通过它们可以实现组件之间的事件通讯。缺点在于,代码量多、组件之易产生藕合引用。
EventBus产生的背景
当我们进行项目开发的时候,经常会遇到组件与组件之间、组件与后台线程之间的通信, 比如:子线程中执行数据请求,数据请求成功后,通过 Handler 或者 BroadCast 来通知UI更新。 两个Fragment之间可以通过Listener进行通信,但是问题来了,当程序越来越大时,就会要写很多的代码, 而且导致代码严重的耦合问题。为此 ,EventBus 应运而生。
EventBus工作流程图解
Publisher使用post发出一个Event事件,Subscriber在onEvent()函数中接收事件。


image.png

EventBus的优势
1,简化组件之间的通讯方式
2,对通信双方进行解藕
3,使用ThreadMode灵活切换工作线程
4,速度快、性能好
5,库比较小,不占内存
EventBus缺点
1、使用的时候有定义很多event类
2、event在注册的时候会调用反射去遍历注册对象的方法在其中找出带有@subscriber标签的方法,性能不高。
3、需要自己注册和反注册,如果忘了反注册就会导致内存泄漏

EventBus环境配置
1,依赖导入
在app module的builde.gradle文件中导入依赖库:

imlementation ‘org.greenrobot:eventbus:3.2.0’

2,配置混淆
必须配置,否则会出现,debug环境正常,release环境接收不到事件的问题

-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);
}

EventBus的使用
EventBus事件三部曲:Subscriber、Event、Publisher。
Subscriber —— EventBus的register方法,会接收到一个Object对象。
Event —— EventBus的post()方法中传入的事件类型 (可以是任意类型)。
Publisher —— EventBus的post()方法。
1,创建一个事件类

public class EventMessage {
    private int type;
    private String message;
    public EventMessage(int type, String message) {
        this.type = type;
        this.message = message;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public String toString() {
        return "type="+type+"--message= "+message;
    }
}

2,在需要订阅事件的模块中,注册EventBus

注意事项:
1,该方法有且仅有一个参数
2,必须用public修饰,不能使用static或者abstract
3,需要添加@Subscribe()注解

public class EventBusActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        //注册EventBus
        EventBus.getDefault().register(this);
    }
 
    //接收事件
    @Subscribe(threadMode = ThreadMode.POSTING, sticky = true, priority = 1)
    public void onReceiveMsg(EventMessage message){
        Log.e("EventBus_Subscriber", "onReceiveMsg_POSTING: " + message.toString());
    }
 
    //接收事件
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 1)
    public void onReceiveMsg1(EventMessage message){
        Log.e("EventBus_Subscriber", "onReceiveMsg_MAIN: " + message.toString());
    }
 
    //接收事件
    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED, sticky = true, priority = 1)
    public void onReceiveMsg2(EventMessage message){
        Log.e("EventBus_Subscriber", "onReceiveMsg_MAIN_ORDERED: " + message.toString());
    }
 
    //接收事件
    @Subscribe(threadMode = ThreadMode.BACKGROUND, sticky = true, priority = 1)
    public void onReceiveMsg3(EventMessage message){
        Log.e("EventBus_Subscriber", "onReceiveMsg_BACKGROUND: " + message.toString());
    }
 
    //接收事件
    @Subscribe(threadMode = ThreadMode.ASYNC, sticky = true, priority = 1)
    public void onReceiveMsg4(EventMessage message){
        Log.e("EventBus_Subscriber", "onReceiveMsg__ASYNC: " + message.toString());
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消事件
        EventBus.getDefault().unregister(this);
    }
}

3,创建订阅者发起通知
使用eventbus.post(eventMessage) 或者 eventbus.postSticky(eventMessage)来发起事件

@OnClick(R2.id.send_event_common)
public void clickCommon(){
    EventMessage message = new EventMessage(1, "这是一条普通事件");
    EventBus.getDefault().post(message);
}
 
@OnClick(R2.id.send_event_sticky)
public void clickSticky(){
    EventMessage message = new EventMessage(1, "这是一条黏性事件");
    EventBus.getDefault().postSticky(message);
}

Subscribe注解介绍
Subscribe是EventBus自定义的注解,共有三个参数(可选):threadMode、boolean sticky、int priority。 完整的写法如下:

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true,priority = 1)
public void onReceiveMsg(EventMessage message) {
    Log.e(TAG, "onReceiveMsg: " + message.toString());
}

1、ThreadMode 模式

用来设置onReceiveMsg()方法,将在哪种线程环境下被调用,共有五种模式:
1.1 POSTING: 默认模式
表示发送事件 post() 发生在哪个线程,接收事件 onReceiveMsg() 就发生在哪个线程环境中。
使用场景:
这种模式不需要线程切换的一些判断逻辑, 直接分发至相同的线程环境,速度快、耗时少。

    订阅处:
    @Subscribe()
    public void onReceiveMsg(EventMessage message) {
        Log.e(TAG, "onReceiveMsg: " + message.toString());
        Log.e(TAG, "onReceiveMsg: current thread name ="+Thread.currentThread().getName() );
    }
    发布处:
    private View.OnClickListener mSendListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.e(TAG, "onClick: " );
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String name = Thread.currentThread().getName();
                    Log.e(TAG, "run: thread  name = "+name );
                    EventMessage msg = new EventMessage(1,"Hello MainActivity");
                    EventBus.getDefault().post(msg);
                }
            }).start();
        }
    };

1.2 MAIN / MAIN_ODERED: 主线程接收事件

表示无论事件在什么线程环境发布 post(),事件的接收总是在主线程环境执行。
二者之间的区别:
1.2.1 对于MAIN模式而言:
如果post事件也在主线程环境,就会阻塞post事件所在的线程环境,通俗点讲,就是在连续的多个post事件的情况下,只有在接收事件的方法执行完,才会执行下一个post事件。
如果post事件不在主线程环境,并且在主线程接收事件中存在耗时操作的话,属于是非阻塞的。
1.2.2 对于MAIN_ORDERED模式而言,无论post事件在哪种线程环境,它的执行流程都是非阻塞的。
1.3 BACKGROUND:
不管post事件发生在那个线程环境, 事件接收始终在一个子线程中执行。
1.4 ASYNC:
该模式表示,不管post事件处于哪种线程环境,事件接收处理总是在子线程。

2、sticky黏性
sticky是一个boolean类型,默认值为false,默认不开启黏性sticky特性,那么什么是sticky特性呢?
上面的例子都是对订阅者 (接收事件) 先进行注册,然后在进行post事件。那么sticky的作用就是:订阅者可以先不进行注册,如果post事件已经发出,再注册订阅者,同样可以接收到事件,并进行处理。
其实就是在sticky场景下,EventBus对事件进行了保存而已。

private View.OnClickListener mGoListener = new View.OnClickListener() {
     @Override
     public void onClick(View v) {
          Log.e(TAG, "onClick: post");
          EventMessage message = new EventMessage(233, "post message before");
          EventBus.getDefault().postSticky(message);
     }
};
 
private View.OnClickListener mRegisterListener = new View.OnClickListener() {
     @Override
     public void onClick(View v) {
          Log.e(TAG, "onClick: start register" );
          //当触发点击事件的时候,才进行注册,这个时候,可同样可以接收到上个点击事件中发出的 事件。
            EventBus.getDefault().register(MainActivity.this);
     }
};

3、priority

priority是优先级,是一个int类型,默认值为0。值越大,优先级越高,越优先接收到事件。
值得注意的是,只有在post事件和事件接收处理,处于同一个线程环境的时候,才有意义。
————————————————
版权声明:本文为CSDN博主「非著名程序员:张张」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_49508485/article/details/127780285

相关文章

  • EventBus

    《EventBus使用详解(一)——初步使用EventBus》 《EventBus使用详解(二)——EventBu...

  • 为什么会用到EventBus,EventBus的源码详解与架构分

    面试官: 为什么会用到EventBus,EventBus的源码详解与架构分析,使用EventBus会造成什么弊端...

  • 自己实现简单的EventBus功能

    1、下面是EventBus3.0的一些用法和源码分析 EventBus使用详解 EventBus源码解析 2、接...

  • EventBus 使用详解

    EventBus 使用详解 概述 EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简...

  • EventBus源码详解,看这一篇就够了

    之前写过一篇关于EventBus的文章,大家的反馈还不错(EventBus3.0使用详解),如果你还没有使用过Ev...

  • EventBus使用详解

    1、EventBus.getDefault().postSticky(new Message(infoList.g...

  • EventBus使用详解

    基本使用 (1)自定义一个类,可以是空类,比如: (2)在要接收消息的页面注册: (3)发送消息 (4)接受消息的...

  • EventBus使用详解

    前言:EventBus出来已经有一段时间了,github上面也有很多开源项目中使用了EventBus。所以抽空学习...

  • EventBus使用详解

    概述 EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递,这...

  • EventBus使用详解

    前言 最近在公司做一个类似于手机工厂模式的一个项目,用来检测其他各个App是否正常工作,所以要求是尽可能的轻量级,...

网友评论

      本文标题:EventBus使用详解

      本文链接:https://www.haomeiwen.com/subject/meqzudtx.html