我的编程空间,编程开发者的网络收藏夹
学习永远不晚

EventBus详解 (详解 + 原理)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

EventBus详解 (详解 + 原理)

一、EventBus的使用介绍

EventBus简介

EventBus是一个开源库,由GreenRobot开发而来,是用于Android开发的 “事件发布订阅总线”, 用来进行模块间通信、解藕。它可以使用很少的代码,来实现多组件之间的通信。 Android系统内置的事件通讯存在缺点: Android系统中的事件通信则是 handler (消息机制) 和 BroadCastReceiver (广播机制), 通过它们可以实现组件之间的事件通讯。缺点在于,代码量多、组件之易产生藕合引用。

EventBus产生的背景

当我们进行项目开发的时候,经常会遇到组件与组件之间、组件与后台线程之间的通信, 比如:子线程中执行数据请求,数据请求成功后,通过 Handler 或者 BroadCast 来通知UI更新。 两个Fragment之间可以通过Listener进行通信,但是问题来了,当程序越来越大时,就会要写很多的代码, 而且导致代码严重的耦合问题。为此 ,EventBus 应运而生。

EventBus工作流程图解

Publisher使用post发出一个Event事件,Subscriber在onEvent()函数中接收事件。      

EventBus的优势

1,简化组件之间的通讯方式 2,对通信双方进行解藕 3,使用ThreadMode灵活切换工作线程 4,速度快、性能好 5,库比较小,不占内存

EventBus缺点

使用的时候有定义很多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 ;}-keep enum org.greenrobot.eventbus.ThreadMode { *; }# Only required if you use AsyncExecutor-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {    (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事件和事件接收处理,处于同一个线程环境的时候,才有意义。

二、EventBus的原理

 清晰讲解:EventBus核心原理其实保存这三张图就可以弄懂了,收藏一下 - 知乎

源码解析:EventBus 原理解析 - 简书

来源地址:https://blog.csdn.net/m0_49508485/article/details/127780285

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

EventBus详解 (详解 + 原理)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解Guava中EventBus的使用

EventBus是Guava的事件处理机制,是设计模式中观察者模式(生产/消费者编程模型)的优雅实现。本文就来和大家聊聊EventBus的使用,需要的可以参考一下
2022-12-23

SpringSecurity基本原理详解

这篇文章主要介绍了SpringSecurity基本原理详解,springsecurity底层实现为一条过滤器链,就是用户请求进来,判断有没有请求的权限,抛出异常,重定向跳转,需要的朋友可以参考下
2023-05-19

MySQL索引原理详解

目录索引是什么索引数据结构树形索引树的动画为什么不是简单的二叉树?为什么不是红黑树?为什么最终选择B+树 而不是B树水平方向可以存放更多的索引key数据量估算叶子节点包含所有的索引字段叶子节点直接包含双向指针,范围查找效率高Hash 索引更
2022-08-19

MySQLCOUNT(*)性能原理详解

这篇文章主要介绍了MySQLCOUNT(*)性能原理详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
2022-11-13

SELINUX工作原理详解

1. 简介SElinux带给Linux的主要价值是:提供了一个灵活的,可配置的MAC机制。 Security-Enhanced Linux (SELinux)由以下两部分组成: 1) Kernel SELinux模块(/ke
2022-06-04

Android 消息分发使用EventBus的实例详解

Android 消息分发使用EventBus的实例详解1. AndroidStudio使用dependencies { //最新版本 compile 'org.greenrobot:eventbus:3.0.0' //可以翻倍提高E
2023-05-30

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录