EventBus使用详解

本文介绍了EventBus的基本使用方法,包括定义消息类、注册与取消订阅事件、发送及处理事件等步骤。同时对比了EventBus与广播的区别,并详细解释了EventBus的线程模型和粘性事件的概念。

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

导入:
compile 'org.greenrobot:eventbus:3.0.0'

一、使用步骤

使用EventBus最大的好处就是简洁代码,简化了activity与activity,activity与fragment,以及fragment之间的数据传递

1、定义一个event消息类

public class MessageEvent {
    ......
}

这个类不需要继承或者实现任何类
2、在需要订阅事件的地方注册事件
一般我们是在onstart()方法中注册,但是如果在消费事件方法执行前,onStart再次执行会报已经注册过的错误,因此也可以在onCreate()中注册

EventBus.getDefault().register(this);

3、发送事件

EventBus.getDefault().post(messageEvent);

4、消费事件(处理事件)

@Subscribe(threadMode = ThreadMode.PostThread)
public void XXX(MessageEvent messageEvent) {
    ...
}

在3.0之前,EventBus还没有使用注解方式。消息处理的方法也只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,分别代表四种线程模型。而在3.0之后,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为PostThread),四种线程模型,下面会讲到。
注意,事件处理函数的访问权限必须为public,否则会报异常。
5、取消订阅事件
同注册事件对应,可以在onStop()或者onDestroy()方法中反注册

EventBus.getDefault().unregister(this);

二、与broadcast对比
1、使用广播实现两个activity之间的消息传递
A跳转到B,B给A发送一个消息
(1)定义一个广播

public class MessageBroadcastReceiver extends BroadcastReceiver {
​
    @Override
    public void onReceive(Context context, Intent intent) {
        mMessageView.setText("Message from SecondActivity:" + intent.getStringExtra("message"));
    }
}

(2)在oncreat方法中注册广播接收器

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //注册事件
    EventBus.getDefault().register(this);
    //注册广播
    IntentFilter intentFilter = new IntentFilter("message_broadcast");
    mBroadcastReceiver = new MessageBroadcastReceiver();
    registerReceiver(mBroadcastReceiver, intentFilter);
    ......
}

(3)在 ondestroy()的方法中取消注册

@Override
protected void onDestroy() {
    super.onDestroy();
   ......
    //取消广播注册
    unregisterReceiver(mBroadcastReceiver);
}

(4)在activityB中发送广播

findViewById(R.id.send_broadcast).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String message = mMessageET.getText().toString();
        if(TextUtils.isEmpty(message)) {
            message = "defaule message";
        }
        Intent intent = new Intent();
        intent.setAction("message_broadcast");
        intent.putExtra("message", message);
        sendBroadcast(intent);
    }
});

2、EventBus实现
(1)定义消息实现类

public class MessageEvent {
​
    private String message;
​
    public MessageEvent(String message) {
        this.message = message;
    }
​
    public String getMessage() {
        return message;
    }
​
    public void setMessage(String message) {
        this.message = message;
    }
}

(2)在A中订阅事件

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //注册事件
    EventBus.getDefault().register(this);
    ......
}

(3)在A中取消订阅

@Override
protected void onDestroy() {
    super.onDestroy();
    //取消事件注册
    EventBus.getDefault().unregister(this);
}

(4)定义消息处理的方法
在注册的地方

@Subscribe(threadMode = ThreadMode.MainThread)
public void onShowMessageEvent(MessageEvent messageEvent) {
    mMessageView.setText("Message from SecondActivity:" + messageEvent.getMessage());
}

(5)在B中发布消息

findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String message = mMessageET.getText().toString();
        if(TextUtils.isEmpty(message)) {
            message = "defaule message";
        }
        EventBus.getDefault().post(new MessageEvent(message));
    }
});

三、常用API介绍
1、线程模型
PostThread:事件的发布线程执行,即同线程,默认的模型
MainThread:主线程,无论在哪个线程发布事件,都在主线程中执行
BackgroundThread:主线程发布,新线程执行,子线程发布,发布线程执行
Async:在子线程执行,无论在哪个线程中执行,都在子线程中执行
2、粘性事件
简单讲,就是在发送事件之后再订阅该事件也能收到该事件,跟黏性广播类似。具体用法如下:
订阅粘性事件:

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

粘性事件的处理

注解中添加sticky=true

@Subscribe(sticky = true)
public void XXX(MessageEvent messageEvent) {
    ......
}

发送粘性事件:

EventBus.getDefault().postSticky(new MessageEvent("test"));

删除粘性事件:
有时候你可能需要删除(消耗)粘性事件,以便它们不再被传递。

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
}

此方法还有一个重载方法:

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

本人水平有限,如有不对的地方,烦请指正,不胜感激!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值