Android开源框架—EventBus

1.EventBus框架
EventBus,即事件总线,一款针对Android优化的发布/订阅事件总线,主要功能是替代Intent,Handler,BroadCast在Fragment、Activity、Service、线程之间传递消息。
它是一个基于观察者模式的事件发布/订阅框架,开发者可以通过极少的代码去实现多个模块之间的通信,而不需要以层层传递接口的形式去单独构建通信桥梁。从而降低因多重回调导致的模块间强耦合,同时避免产生大量内部类。
如下图所示即EventBus的运行框架。
EventBus运行框架
EventBus主要用于同一进程间通信,支持多线程通信。(跨进程通信可以用广播)

2.EventBus使用了发布者/订阅者模式。
在EventBus中主要有以下三个成员:
①Event:事件,可以自定义为任意对象,类似Message类的作用;
②Publisher:事件发布者,可以在任意线程、任意位置发布Event,已发布的Event则由EventBus进行分发;
③Subscriber:事件订阅者,接收并处理事件,需要通过register(this)进行注册,而在类销毁时要使用unregister(this)方法解注册。每个Subscriber可以定义一个或多个事件处理方法,其方法名可以自定义,但需要添加@Subscribe的注解,并指明ThreadMode(不写默认为Posting)。
发布者通过EventBus发布事件,订阅者通过EventBus订阅事件。当发布者发布事件时,订阅该事件的订阅者的事件处理方法将被调用。
注意:订阅者可以订阅多个事件,发布者可以发布任何事件,发布者同时也可以是订阅者。

3.EventBus使用流程
要使用EventBus,首先需要在build.gradle 中添加EventBus的依赖:
dependencies {

compile ‘org.greenrobot:eventbus:3.1.1’
}
接下来开始使用EventBus,主要分为3个步骤:定义事件、订阅事件、发布事件。
①定义事件。事件可以是任意普通的Java对象,没有任何特殊的要求。
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;
}
}
②订阅事件。订阅者需要定义事件处理方法(也称为订阅者方法)。当发布对应类型的事件时,该方法将被调用。
在EventBus2.x的时候,订阅者方法都是固定函数名,而EventBus3以后使用 @Subscribe 注解来定义订阅者方法,方法名可以是任意合法的方法名,参数类型为订阅事件的类型。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {

}
订阅者还需要在总线上注册,并在不需要时在总线上注销。只有订阅者注册了,它们才会收到事件。在Android中,可以根据Activity或者Fragment的生命周期来注册和注销。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initContentView();
// 注册订阅者
EventBus.getDefault().register(this);
}

@Override
protected void onDestroy() {
super.onDestroy();
// 注销订阅者
EventBus.getDefault().unregister(this);
}
③发布事件。在需要的地方发布事件,所有订阅了该类型事件并已注册的订阅者将收到该事件。
// 发布事件
EventBus.getDefault().post(new MessageEvent(“Hello EventBus!”));

4.实例
下面是一个EventBus的例子。
订阅事件的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = “MainActivity”;
private TextView mTvMessage;

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

private void initContentView() {
Button btnStart = findViewById(R.id.btn_main_start_activity);
mTvMessage = findViewById(R.id.tv_main_message);
btnStart.setOnClickListener(this);
}

@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_main_start_activity) {
Intent intent = new Intent(this, SecondActivity.class);
context.startActivity(intent);
}
}

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Log.i(TAG, "message is " + event.getMessage());
// 更新界面
mTvMessage.setText(event.getMessage());
}

@Override
protected void onDestroy() {
super.onDestroy();
// 注销订阅者
EventBus.getDefault().unregister(this);
}

MainActivity订阅了MessageEvent事件。当接收到MessageEvent事件时,订阅者方法将打印日志消息,并更新界面上的TextView。

发布事件的代码:
public class SecondActivity extends AppCompatActivity implements View.OnClickListener {

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

private void initContentView() { findViewById(R.id.btn_second_post_event).setOnClickListener(this);
}

@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_second_post_event) {
// 发布事件
EventBus.getDefault().post(new MessageEvent(“Hello EventBus!”));
}
}
}
当点击发布事件的按钮时,SecondActivity将发布一个MessageEvent事件。

运行应用。点击MainActivity界面上的启动活动按钮来启动SecondActivity,然后点击SecondActivity界面上的发布事件按钮来发布事件。最后,回退到MainActivity,可以看到界面上的TextView的内容已经更新为”Hello EventBus!”,并且应用打印出如下信息:
message is Hello EventBus!

5.线程模式
EventBus支持订阅者方法在不同于发布事件所在线程的线程中被调用。你可以使用线程模式来指定调用订阅者方法的线程。
EventBus总共支持5种线程模式:
①ThreadMode.POSTING
订阅者方法将在发布事件所在的线程中被调用。这是 默认的线程模式。事件的传递是同步的,一旦发布事件,所有该模式的订阅者方法都将被调用。这种线程模式意味着最少的性能开销,因为它避免了线程的切换。因此,对于不要求是主线程并且耗时很短的简单任务推荐使用该模式。使用该模式的订阅者方法应该快速返回,以避免阻塞发布事件的线程,这可能是主线程。
②ThreadMode.MAIN
订阅者方法将在主线程(UI线程)中被调用。因此,可以在该模式的订阅者方法中直接更新UI界面。如果发布事件的线程是主线程,那么该模式的订阅者方法将被直接调用。使用该模式的订阅者方法必须快速返回,以避免阻塞主线程。
③ThreadMode.MAIN_ORDERED
订阅者方法将在主线程(UI线程)中被调用。因此,可以在该模式的订阅者方法中直接更新UI界面。事件将先进入队列然后才发送给订阅者,这使得事件的处理保持严格的串行顺序。使用该模式的订阅者方法必须快速返回,以避免阻塞主线程。
④ThreadMode.BACKGROUND
订阅者方法将在后台线程中被调用。如果发布事件的线程不是主线程,那么订阅者方法将直接在该线程中被调用。如果发布事件的线程是主线程,那么将使用一个单独的后台线程,该线程将按顺序发送所有的事件。使用该模式的订阅者方法应该快速返回,以避免阻塞后台线程。
⑤ThreadMode.ASYNC
订阅者方法将在一个单独的线程中被调用,因此,发布事件的调用将立即返回。如果订阅者方法的执行需要一些时间,例如网络访问,那么就应该使用该模式。避免触发大量的长时间运行的订阅者方法,以限制并发线程的数量。EventBus使用了一个线程池来有效地重用已经完成调用订阅者方法的线程。
下面是一个例子,来说明这五种线程模式的区别。
public class EventBusActivity extends AppCompatActivity {
private TextView tv_Event;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_bus);
//注册事件
EventBus.getDefault().register(this);
Thread thread1 = new Thread(new myThread1());
thread1.start();
}

//事件处理方法
&#

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值