线程Android知识Android开发

Android 框架之EventBus(一)

2017-02-28  本文已影响771人  王世军Steven

EventBus 是一个Android端优化的 publish/subscribe 消息总线,简化了应用程序各个组件间(Activity,Service,Fragment等),组件和后台线程间的通信. 比如网络请求 , 等网络返回时通过Handler 或者 Broadcast 通知 UI , Fragment之间的通信 等功能都可以通过EventBus 实现.

EventBus-Publish-Subscribe.png

相关链接 :

EventBus 基本使用

compile 'org.greenrobot:eventbus:3.0.0'
public class EventBusMsg {
    // 类的结构是自定义的,我这类添加了一个 String类型的 name 字段 方便测试.
    public String name;

    public EventBusMsg(String name) {
        this.name = name;
    }
}
public void sendMsg(View view) {
    // 发送消息
    EventBus.getDefault().post(new EventBusMsg("我是EventBus发送的数据"));
    // 销毁当前Activity
    finish();
}

到此我们就完成了EventBus的最基本使用 , 我在MainActivity中注册了事件监听,然后跳转到EventBusSendActivity 中发布事件,事件发布完成后销毁EventBusSendActivity,此时跳转到MainActivity中,使用一个TextView打印刚才发布的时间的name.
注意 : 上面这中用法一定要先订阅事件在进行发布事件才可以接收到事件,当然也可以实现先发布在订阅的模式,后面会介绍

EventBus 事件回调方法线程(Delivery Thread)

EventBus会处理事件接收线程的问题 , 比如可以将消息发送到另外一个线程中,比如 : 在 线程A 中发布事件. 事件传递到线程B中执行. 这个功能主要用在处理更新UI的问题上,我们都知道在Android中只有在UI线程中才可以更新UI,否则会引发异常.但是一下耗时操作比如网络请求等又必须在子线程中执行, 此时 EventBus就可以帮助我们处理UI和后台任务的同步问题 . 就好像Android自带的Handler 和 Broadcast机制一样.
EventBus有四种线程模式 , 可以通过@Subscribe()注解的threadMode参数进行指定.

// 运行在发布消息的线程中 (default)
// ThreadMode 是可选设置
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
    log(event.message);
}
// 运行在 UI 线程中(主线程)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
// 运行在后台线程中.
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
    saveToDisk(event.message);
}
// 运行在一个独立的线程中.
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
    backend.send(event.message);
}

EventBus 高级一点的用法 : 粘性事件(Stick Events)

在EventBus的基本使用中我们说过那种模式必须要先订阅事件然后再发布事件. 这次我们来尝试一下EventBus另一种用法 粘性事件,在这种模式允许先发布事件再订阅事件 . EventBus会将粘性事件保存在内存中然后发送给订阅者,订阅者也可以主动查询粘性事件.

public class EventBusStickyMsg {
    public String name;
    public EventBusStickyMsg(String name) {
        this.name = name;
    }
}
public void sendStickyEvent(View view) {
    EventBus.getDefault().postSticky(new EventBusStickyMsg("我是Sticky消息"));
    // 启动 EventBusSendActivity
    Intent intent = new Intent(MainActivity.this, EventBusSendActivity.class);
    MainActivity.this.startActivity(intent);
}

注意 : 不要进行重复注册,可能造成程序崩溃

  @Override
  protected void onDestroy() {
      super.onDestroy();
      // 移除所有的粘性事件.
      EventBus.getDefault().removeAllStickyEvents();
      // 解注册
      EventBus.getDefault().unregister(EventBusSendActivity.this);
  }
  @Subscribe(sticky = true , threadMode = ThreadMode.MAIN)
  public void onStickyEvent(EventBusStickyMsg event) {
      tv_console.setText("Sticky 数据 : " + event.name);
  }

粘性事件接收方法需要在@Subscribe()注解中添加sticky = true 参数.

到此粘性事件的使用就完成了. 程序流程大概如下 :

  1. 在MainActivity中发布粘性事件.
  2. 在EventBusSendActivity中注册事件.
  3. 在TextView上显示事件.

上面我们使用的是订阅方式获取事件. 我们也可以手动获取粘性事件,我们添加一个Button在点击事件中添加如下代码

public void getStickyMsgManually(View view) {
    // 手动获取粘性事件
    EventBusStickyMsg msg = EventBus.getDefault().getStickyEvent(EventBusStickyMsg.class);
    if (msg != null) {
        tv_console.setText(tv_console.getText().toString() + msg.name);
        // 删除事件
        EventBus.getDefault().removeStickyEvent(msg);
    }
}

我们首先使用getStickyEvent()方法获取粘性事件 , 但是我们获取了该粘性事件后 , EventBus并不会主动删除该粘性事件,(订阅方式也不会删除), 所以我们主动调用了removeStickyEvent() 方法删除粘性事件.

同时我们通过查看removeStickyEvent()方法返回值可以发现 , 他会将删除的事件返回,因此我们修改代码如下.

public void getStickyMsgRemove(View view) {
    // 手动获取粘性事件
    EventBusStickyMsg msg = EventBus.getDefault().removeStickyEvent(EventBusStickyMsg.class);
    if (msg != null) {
        tv_console.setText(tv_console.getText().toString() + msg.name);
    }
}

OK 到此关于EventBus的基本使用已经介绍完毕,我们主要介绍了一下三点内容 :

Demo 下载地址 : http://download.csdn.net/detail/qq_16188829/9766568

上一篇下一篇

猜你喜欢

热点阅读