EventBus使用详解

Vue事件总线(EventBus)、$on、$emit、$off 在之前我们只用过父传子,子传父进行传数据,这时候当组件嵌套比较深或比较复杂的情况,这时候就用到了事件总线 (EventBus) 如何理解事件总线呢,你可以理解为用来传输数据的一条线 一、使用EventBus 1. 创建事件总线 main.js // 创建事件总线 const bus = new Vue() // 把bus挂载到了Vue的原型上, 保证所有的组件都能通过 this.$bus访问到事件总线 Vue.prototype.$bus = bus 2.页面使用 发布事件 - 传... 阅读详情

概述

EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递,这里的事件可以理解为消息。事件传递既可以用于Android四大组件间通讯,也可以用于异步线程和主线程间通讯等。
传统的事件传递方式包括:Handler、BroadcastReceiver、Interface回调,相比之下EventBus的有点是代码简洁,使用简单,并将事件发布和 订阅充分解耦。

概念

事件Event: 又可成为消息,其实就是一个对象,可以是网络请求返回的字符串,也可以是某个开关状态等等。事件类型EventType是指事件所属的Class。

事件分为一般事件和Sticky事件,相对于一般事件,Sticky事件不同之处在于,当事件发布后,再有订阅者开始订阅该类型事件,依然能收到该类型事件的最近一个Sticky事件。

订阅者Subscriber: 订阅某种事件类型的对象,当有发布者发布这类事件后,EventBus会执行订阅者的onEvent函数,这个函数叫事件响应函数。订阅者通过register接口订阅某个事件类型,unregister接口退订。订阅者存在优先级,优先级高的订阅者可以取消事件继续向优先级低的订阅者分发,默认所有订阅者优先级都为0。

发布者Publisher: 发布某事件的对象,通过post接口发布事件。

GitHub地址

EventBus源码:https://github.com/greenrobot/EventBus

基本使用

自定义一个事件类

public class AnyEventType {
     public AnyEventType(){}
 }

在要接受消息的页面注册

EventBus.getDefault().register(this);

接收消息的方法

@Subscribe
public void onEvent(AnyEventType event) {/* Do something */};

发送消息

EventBus.getDefault().post(event);

取消注册

EventBus.getDefault().unregister(this);

实例

下面我们来实现一个具体的例子来介绍EventBus的基本使用。

需求如下:在MainActivity中注册EventBus事件,并实现事件响应方法,当点击MainActivity中的按钮时跳转到SecondActivity,当点击SecondActivity中的按钮时向MainActivity发送Event事件,当MainActivity收到事件后,将事件内容显示在TextView中。

  1. MainActivity


    MainActivity
  2. SecondActivity


  3. 事件处理


事件类Event

public class Event {

    private String messgae;

    public Event(String messgae) {
        this.messgae = messgae;
    }

    public String getMessgae() {
        return messgae;
    }
}

MainActivity

在OnCreate()函数中注册EventBus,在Ondestroy()函数中反注册。

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.btn_open)
    Button mOpenBtn;

    @Bind(R.id.tv_showinfo)
    TextView mInfoTxt;


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

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

    }

    /**
     * 事件响应方法
     * 接收消息
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(Event event) {

        String msg = event.getMessgae();
        mInfoTxt.setText(msg);
    }

    //绑定点击事件
    @OnClick(R.id.btn_open)
    public void openSecondActivity(View view) {
            Intent intent = new Intent(MainActivity.this, SecondActivity.class);
            startActivity(intent);

    }


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

SecondActivity

public class SecondActivity extends AppCompatActivity {

    @Bind(R.id.btn_post)
    Button mPostBtn;

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

        ButterKnife.bind(this);


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

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //发送事件
                        EventBus.getDefault().post(new Event("Just do it"));
                    }
                }).start();

            }
        });
    }

}

EventBus的事件订阅函数

类别

在上面的例子中,我们再注解@Subscribe(threadMode = ThreadMode.MAIN)中使用了ThreadMode.MAIN这个模式,表示该函数在主线程即UI线程中执行,实际上EventBus总共有四种线程模式,分别是:

  • ThreadMode.MAIN:表示无论事件是在哪个线程发布出来的,该事件订阅方法onEvent都会在UI线程中执行,这个在Android中是非常有用的,因为在Android中只能在UI线程中更新UI,所有在此模式下的方法是不能执行耗时操作的。

  • ThreadMode.POSTING:表示事件在哪个线程中发布出来的,事件订阅函数onEvent就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。

  • ThreadMode.BACKGROUND:表示如果事件在UI线程中发布出来的,那么订阅函数onEvent就会在子线程中运行,如果事件本来就是在子线程中发布出来的,那么订阅函数直接在该子线程中执行。

  • ThreadMode.AYSNC:使用这个模式的订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程来执行订阅函数。

实战

如何调用不同的订阅函数

要调用四种不同模式的订阅函数,我们首先要用清楚EventBus是如何指定调用的函数的?

先回顾一下上一节中的例子是如何调用订阅函数onEvent的,首先新建一个事件类:

public class Event {

    private String messgae;

    public Event(String messgae) {
        this.messgae = messgae;
    }

    public String getMessgae() {
        return messgae;
    }
}

发布事件:

EventBus.getDefault().post(new Event("Just do it"));

订阅事件:

    /**
     * 事件响应方法
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMain(Event event) {

        String msg = event.getMessgae();
        mInfoTxt.setText(msg);
    }

观察可以发现:发布事件中的参数是Event的实例,而订阅函数中的参数也是Event的实例,可以推断EventBus是通过post函数传进去的类的实例来确定调用哪个订阅函数的,是哪个就调用哪个,如果有多个订阅函数呢,那么这些函数都会被调用!

示例

下面我们来验证这个推断:

我们在基本使用章节的例子上进行扩展,首先建立四个类:FirstEvent、SecondEvent、ThirdEvent、FourthEvent。

FirstEvent.java

public class FirstEvent {

    private String messgae;

    public FirstEvent(String messgae) {
        this.messgae = messgae;
    }

    public String getMessgae() {
        return messgae;
    }
}

SecondEvent.java

public class SecondEvent {

    private String messgae;

    public SecondEvent(String messgae) {
        this.messgae = messgae;
    }

    public String getMessgae() {
        return messgae;
    }
}

ThirdEvent.java

public class ThirdEvent {

    private String messgae;

    public ThirdEvent(String messgae) {
        this.messgae = messgae;
    }

    public String getMessgae() {
        return messgae;
    }
}

FourthEvent.java

public class FourthEvent {

    private String messgae;

    public FourthEvent(String messgae) {
        this.messgae = messgae;
    }

    public String getMessgae() {
        return messgae;
    }
}

然后在MainActivity中,增加四种模式的订阅函数

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Bind(R.id.btn_open)
    Button mOpenBtn;

    @Bind(R.id.tv_showinfo)
    TextView mInfoTxt;


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

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

    }

    /**
     * 事件响应方法
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMain(FirstEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventMain: " + event.getMessgae());
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEventPosting(SecondEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventPosting: "+ event.getMessgae());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventBackgroud(ThirdEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventBackgroud: " + event.getMessgae());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEventAsync(FourthEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventAsync: " + event.getMessgae());
    }

    //绑定点击事件
    @OnClick(R.id.btn_open)
    public void openSecondActivity(View view) {
            Intent intent = new Intent(MainActivity.this, SecondActivity.class);
            startActivity(intent);

    }


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

接下来在SecondActivity中增加四个按钮,分别发送不同类别的事件

public class SecondActivity extends AppCompatActivity {

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

        ButterKnife.bind(this);
    }

    @OnClick(R.id.btn_post)
    public void onPostA() {
        EventBus.getDefault().post(new FirstEvent("FirstEvent"));
    }

    @OnClick(R.id.btn_post2)
    public void onPostB() {

        EventBus.getDefault().post(new SecondEvent("SecondEvent"));
    }

    @OnClick(R.id.btn_post3)
    public void onPostC() {

        EventBus.getDefault().post(new ThirdEvent("ThirdEvent"));
    }

    @OnClick(R.id.btn_post4)
    public void onPostD() {

        EventBus.getDefault().post(new FourthEvent("FourthEvent"));
    }
}

运行后,分别顺序点击SecondActivity的四个按钮,打印信息如下:

03-31 02:53:45.950 4779-4779/com.example.michael.eventbusdemo I/MainActivity: onEventMain: FirstEvent
03-31 02:53:47.528 4779-4779/com.example.michael.eventbusdemo I/MainActivity: onEventPosting: SecondEvent
03-31 02:53:48.882 4779-4940/com.example.michael.eventbusdemo I/MainActivity: onEventBackgroud: ThirdEvent
03-31 02:53:50.462 4779-4940/com.example.michael.eventbusdemo I/MainActivity: onEventAsync: FourthEvent

由此可见,通过发布不同的事件类的实例,EventBus根据类的实例分别调用了不同的订阅函数来处理事件。

那么,当同一个类的实例有多个函数订阅时,结果会是怎样呢?答案是,这些函数都会执行。下面我们来验证一下,将MainActivity中订阅函数的参数都改为FirstEvent,代码如下:

   /**
     * 事件响应方法
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMain(FirstEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventMain: " + event.getMessgae());
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEventPosting(FirstEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventPosting: "+ event.getMessgae());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventBackgroud(FirstEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventBackgroud: " + event.getMessgae());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEventAsync(FirstEvent event) {

        String msg = event.getMessgae();
        Log.i(TAG, "onEventAsync: " + event.getMessgae());
    }

运行程序,点击SecondActivity的FirstEvent按钮,打印信息如下:

03-31 03:14:07.032 23611-23746/com.example.michael.eventbusdemo I/MainActivity: onEventAsync: FirstEvent
03-31 03:14:07.033 23611-23611/com.example.michael.eventbusdemo I/MainActivity: onEventMain: FirstEvent
03-31 03:14:07.033 23611-23611/com.example.michael.eventbusdemo I/MainActivity: onEventPosting: FirstEvent
03-31 03:14:07.034 23611-23748/com.example.michael.eventbusdemo I/MainActivity: onEventBackgroud: FirstEvent

分析可知,当SecondActivity发送FirstEvent事件过来的时候,这个四个订阅函数会同时接收到这个事件并执行。

总结: 订阅函数的执行是根据参数中的事件类的类名来决定的。

参考:

EventBus 源码解析 使用方法 使用方法很简单,按照官方文档介绍,分为三个步骤。 步骤1:定义事件 public static class MessageEvent { } 步骤2:准备订阅者 定义订阅方法,来处理收到的事件。 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) {/* Do something */}; 并在Activity、Fragment中按照其生命周期进行注册与注销。 @O 阅读详情

相关推荐

Eventbus3.X使用详解

本文详细介绍了EventBus 3.3.1在Android Kotlin项目中的完整使用指南。主要内容包括:1)依赖配置,强调必须开启kapt注解处理器;2)核心使用流程(定义事件类、订阅者注册、发送事件、解注册);3)粘性事件等高级用法;4)@Subscribe注解参数详解;5)Kotlin专属注意事项;6)常见问题排查方法。文章提供了可直接运行的代码示例,特别强调了线程模式选择、注册解注册配对、混淆规则等关键点,帮助开发者快速掌握EventBus在Kotlin项目中的正确使用方式。

fuge2008的博客 953

EventBus详解 (详解 + 原理)

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

m0_49508485的博客 4万+

EventBus简单介绍

EventBus简单介绍

是阿超 2942

EventBus源码赏析一 —— 基本使用

EventBus简介 EventBus是一种用于Android的发布/订阅事件总线。我们经常用来在不同界面,不同线程传递数据,它解耦了事件发送方和事件处理方。 虽然Android本身提供了LocalBroadcastReceiver类可以实现类似的功能,但是LocalBroadcastReceiver使用起来稍微繁琐,而且传递数据大小也受intent限制。 EventBus角色 EventBus主要有一下三个角色: Event 事件,可以是任意引用类型,不能是基础数据类型如int,char。他是Event

Android23333的博客 1700

自适应粒子群优化(Adaptive Particle Swarm Optimization,APSO

下面是一个关于自适应粒子群优化(Adaptive Particle Swarm Optimization,APSO)的博客,希望可以帮助您。提示:以下是本篇文章正文内容,下面案例可供参考在上面的代码中,表示粒子的数量,表示解空间的维度,表示迭代次数,表示优化的目标函数。在__init__方法中,我们初始化了粒子群的位置和速度,并将每个粒子的位置作为其最优解,将其适应度值初始化为正无穷。我们还初始化了学习因子和惯性权重的参数。在run方法中,我们迭代了次,计算每个粒子的适应度值和最优解。

weixin_52026057的博客 9914

【SAP报错】BK128&K5112

在ECC中使用CO1F进行Progressive confirmation时,依次遇到了如下的报错。

weixin_45228526的博客 783

EventBus的使用详解

EventBus的使用详解     Eclipse用户请下载EventBus的源码导入 源码地址:https://github.com/greenrobot/EventBus         EventBus是一个Android 端优化的Publish/Subscribe 消息总线,它简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络等网络返回

苍穹之上倚天长鸣的博客 1454

YOLOv5添加注意力机制的具体步骤

本文主要介绍了 本文在此篇博客的基础上向YOLOv5-5.0版 本文主要包括以下内容一、CBAM注意力机制添加(1)修改yolov5s主干网络(2)在common.py中添加可调用的CBAM模块(3)向yolo.py文件添加CBAMC3判断语句二、SE注意力机制添加 本文以yolov5s网络为例 一、CBAM注意力机制添加 注意力机制可以添加在backbone,Neck,Head等部分,接下来本文以backbone主干网络为例 (1)修改yolov5s主干网络 1.在yolov5-5.0工程文件夹下,找到m

thy0000的博客 2万+

EventBus使用详解(二)——EventBus使用进阶

前言:这段时间感觉自己也有点懒了,真是内心有点自责呢,除了工作,也没做点什么,EventBus也是一周前总结出来的,只能以写博客为名来弥补内心的罪恶感了,集合同事们做的项目,虽然上周开动了,但总感觉大家积极性不高,如何才能做一个合格的管理者,还真是一个考验。follow your heart!! just do it! 相关文章: 1、《EventBus使用详解(一)——初步使用E...

启舰 13万+

无人机上下通信信号解析程序和代码

总的来说,无人机上下行信号解析是无人机系统中非常重要的一部分,它关系到无人机的飞行控制和图像传输能力,对于保障无人机的飞行安全和数据传输质量具有重要作用。3. 读取和解析地面控制中心发送的命令和数据:程序还需要能够读取地面控制中心发送给无人机的命令和数据。1. 读取和解析无人机发送的命令和数据:程序需要能够读取无人机发送的信号,并解析其中的命令和数据。4. 将解析结果传递给无人机:解析地面控制中心发送的命令和数据后,程序需要将解析结果传递给无人机。具体的实现方式可以根据无人机的通信协议和硬件设备来确定。

2401_84824274的博客 2189

从PX4的FRD到Mavros的FLU:手把手教你正确配置`setpoint_raw/local`话题发布无人机目标点

本文详细解析了PX4的FRD与Mavros的FLU坐标系转换问题,手把手教你正确配置`setpoint_raw/local`话题发布无人机目标点。通过实战指南和常见错误排查,帮助开发者避免方向错乱问题,提升无人机控制精度。

weixin_33712987的博客 422

EventBus 使用详解

目录EventBus的概述 EventBus的概述 三要素 Event 事件。它可以是任意类型。 Subscriber事件订阅者。在EventBus3.0之前我们必须定义以onEvent开头的那几个方法,分别是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@...

qq_30172399的博客 444

29、高速低功耗采样保持放大器设计

本文详细介绍了适用于低功耗模数转换器的高速低电压采样保持放大器(SHA)的设计技术,包括传统SHA的局限性、采样技术分类以及全NPN型和BiCMOS型SHA的具体设计实现。同时,文章深入探讨了优化输入电容、采样开关驱动及低功耗设计等具体措施,并提供了10位ADC前端和无线通信应用中的实例分析,为相关领域的工程师提供有价值的参考。

weixin_30600615的博客 424

Eventbus的使用详解

EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更简单优雅,使用方便快捷,利于开发。

天涯过客的博客 303

如何在SpringBoot中实现AI 流式输出?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1479

【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法

相比C文本类编程语言,Simulink图形化编程语言的优势是逻辑思路和数据流清晰了很多,劣势是程序执行的时序不明确,而且各个模块的配置使编程的灵活度下降了不少,在使用习惯上面总感觉有各种限制。本文就是拆解Simulink中最基础的几个编程模块,发扬它的优势,避开劣势。

Mr.Cssust的博客 3849

EventBus使用详解——初步使用EventBus

前言:EventBus是上周项目中用到的,网上的文章大都一样,或者过时,有用的没几篇,经过琢磨,请教他人,也终于弄清楚点眉目,记录下来分享给大家。 相关文章: 1、《EventBus使用详解(一)——初步使用EventBus》 2、《EventBus使用详解(二)——EventBus使用进阶》 一、概述 EventBus是一款针对Android

Lin_XiJun的博客 258

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: EventBus 3.0的用法详解(二)
下一篇: Android中使用的LruCache
dwf_学海无涯
博客等级 码龄10年 42粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值