EventBus的使用

本文详细介绍了EventBus在Android应用中如何实现组件间高效事件传递,包括其核心概念、使用方法及与其他机制如广播的区别。通过具体实例展示了如何在Adapter与Activity之间进行值的传递,并深入探讨了EventBus的回调机制与线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EventBus用了好久了,一直没有整理一下。
我们往简单里说,EventBus的出现,让我们在大部分情况下,不需要使用broadcast来在不同的activity,fragment,甚至是adapter(我知道你们经常纠结adapter和activity的交互!)之间交互了。
当然,如果你要获取系统广播什么的,还是需要broadcast的。
而且EventBus的回调很丰富,你甚至可以指定你的回调运行在哪个线程里(这个很方便有木有)

我们举一个例子来说明一下:
废代码我们就不写了,省得大家看起来乱。
我们来举一个从adapter到activity传值的例子。
首先我们有一个adapter,叫ListAdapter,我们打算在点击ListAdapter中某个item的按钮时,发送一个消息到MainActivity,MainActivity接收一个消息后,弹出一个toast提示框。
跟动态广播一样,首先我们要为每一个广播指定类型,所以我们写了一个Event类:

public class Event<T> {
    private EventType eventType;
    private T message;

    public Event(EventType eventType) {
        this.eventType = eventType;
    }

    public Event(EventType eventType, T message) {
        this.eventType = eventType;
        this.message = message;
    }

    public EventType getEventType() {
        return eventType;
    }

    public void setEventType(EventType eventType) {
        this.eventType = eventType;
    }

    public T getMessage() {
        return message;
    }

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

以及定义了几种事件:

public enum EventType {
    START_MINING, 
    ENTER_GAME_TAB,   
}

定义完了后,首先我们要在MainActivity的onCreate方法中注册一个EventBus:

EventBus.getDefault().register(this);

并在onDestroy方法中反注册它:

EventBus.getDefault().unregister(this);

这样,MainActivity就可以接收到EventBus的消息了。
然后我们要在ListAdapter里面发送消息:

        holder.image_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //这里,我们在按钮的点击事件里发送消息
                EventBus.getDefault().post(
                        new Event(EventType.START_MINING, getItem(pos).mountainLevel));
            }
        });

梳理一下,现在我们完成了消息发送和消息接收方的注册了。那对比广播,我们还需要一个接受消息的地方。
其实很简单,我们回到MainActivity,写一个方法:

    public void onEventMainThread(Event event) {

        String msg = "onEventMainThread收到了消息:" + event.getMessage();
        Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
    }

然后这个方法会自动接收MainActivity收到的消息。
是不是很奇怪,为什么我随便定义了一个方法,既没有指定这个方法接收消息,而且这个方法也不是我重写的?(比如继承了EventBus类,然后重写它的接收方法)
最初我也很奇怪,所以我做了一个实验,我把onEventMainThread改名了,改成offEventMainThread,结果居然运行报错,大致意思是说,我在MainActivity中注册了EventBus,但是我没有指定接收方法!
又找了些资料研究了下,EventBus应该是注册了之后,就会在这个类MainActivity装载的时候,自动扫描是否有接收方法,如果没有就直接抛出异常

除了onEventMainThread,EventBus还有别的接收方法,我直接饮用了别的资料:

EventBus还有另外有个不同的函数,他们分别是:
1、onEvent
2、onEventMainThread
3、onEventBackgroundThread
4、onEventAsync
这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:
告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下面的订阅函数实现的。
onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值