前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >EventBus3 学习笔记

EventBus3 学习笔记

作者头像
佛系编码
发布2018-05-22 11:18:54
6290
发布2018-05-22 11:18:54
举报
文章被收录于专栏:Android学习之路Android学习之路

脑图

EventBus学习笔记
EventBus学习笔记

概述

EventBus 是一款针对Android优化的发布/订阅(publish/subscribe)事件总线。主要功能是替代Intent,Handler,Broadcast在Fragment,Activity,Service,线程之间传递消息。简化了应用程序内各组件,组件与后台线程间的通信。优点代码简洁,以及将发送者和订阅者解耦。

基本使用

使用步骤

  • 添加依赖
  • 定义事件
  • 注册/取消订阅
  • 发送事件

添加依赖

代码语言:javascript
复制
compile 'org.greenrobot:eventbus:3.0.0'

定义事件

这里的事件是一个任意的POJO 没有任何要求

代码语言:javascript
复制
public class MessageEvent {

    public final String message;

    public MessageEvent(String message) {
        this.message = message;
    }
}

订阅

准备订阅者

使用注解 @Subscribe ,在3.0中对方法名称没有任何要求 当发送事件时EventBus会调用方法

代码语言:javascript
复制
// This method will be called when a MessageEvent is posted (in the UI thread for Toast)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

// This method will be called when a SomeOtherEvent is posted
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
    doSomethingWith(event);
}

注册/取消订阅

代码语言:javascript
复制
@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

发送事件

代码语言:javascript
复制
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

官网指南 http://greenrobot.org/eventbus/documentation/how-to-get-started/

交付线程 Delivery Threads (ThreadMode)

EventBus 通过 threadMode 决定订阅事件 在哪个线程处理,threadMode的取值 有四个枚举类型

  • POSTING
  • MAIN
  • BACKGROUND
  • ASYNC

POSTING。 默认值,将会与发送线程一致,发送事件在哪个线程,订阅者就在哪个线程处理

代码语言:javascript
复制

// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
    log(event.message);
}

MAIN 。 UI线程,订阅者将会在UI线程处理

代码语言:javascript
复制

// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}

BACKGROUND 。 后台线程处理,如果发送者在UI线程发出就会另开线程处理,否则就直接在同一线程处理,不会在UI线程处理就对了

代码语言:javascript
复制

// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
    saveToDisk(event.message);
}

ASYNC 。异步,订阅者将会另开一个线程处理,无论发送者从哪个线程发出

代码语言:javascript
复制

// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
    backend.send(event.message);
}

官网指南 http://greenrobot.org/eventbus/documentation/delivery-threads-threadmode/

优先级及事件取消 Priorities and Event Cancellation

优先级

EventBus 通过 priority 属性决定优先级 ,默认0 值越高 优先级越高。

代码语言:javascript
复制

@Subscribe(priority = 1);
public void onEvent(MessageEvent event) {
    ...
}

事件取消

EventBus 通过 cancelEventDelivery(Object event) 取消事件,这可是优先级高的特权了。

代码语言:javascript
复制

// Called in the same thread (default)
@Subscribe
public void onEvent(MessageEvent event){
    // Process the event
    ...
    // Prevent delivery to other subscribers
    EventBus.getDefault().cancelEventDelivery(event) ;
}

官网指南 http://greenrobot.org/eventbus/documentation/priorities-and-event-cancellation/

配置 Configuration

一般我们使用 EventBus.getDefault() 得到EventBus实例, 如果有别的需求可以使用 EventBusBuilder 类构建EventBus,例如 关闭log

代码语言:javascript
复制
EventBus eventBus = EventBus.builder()
    .logNoSubscriberMessages(false)
    .sendNoSubscriberEvent(false)
    .build();

或者说 当订阅者抛出异常时 发送 SubscriberExceptionEvent 事件

代码语言:javascript
复制
EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();

默认情况下 订阅者抛出异常EventBus会捕获异常并发一个 SubscriberExceptionEvent 事件

我们可以通过 installDefaultEventBus()方法我们的配置放到默认实例上;但是要在使用 EventBus.getDefault()之前

代码语言:javascript
复制
EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();

官网指南 http://greenrobot.org/eventbus/documentation/configuration/

粘性事件 Sticky Events

对于一般的事件,我们首先要注册订阅者,然后发送事件,订阅者才能收到事件。如果先发送事件,再订阅此事件,将收不到事件,而粘性事件恰恰相反,粘性事件是可以先发送,然后再注册订阅者,后注册的订阅者依然可以接收到事件(ps:在发送前注册的也可以收到)

先发送粘性事件

代码语言:javascript
复制
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));

再启动一个Activity 仍然可以接受到之前发送的事件

属性 sticky 的取值决定是否是粘性事件

ps:你不注册的话,啥事件也是收不到的

代码语言:javascript
复制
@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

// UI updates must run on MainThread
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);    
    super.onStop();
}

移除粘性事件

如果你不移除粘性事件,那么它将一直存在,直到你程序被杀死

代码语言:javascript
复制
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
}

官网传送门 http://greenrobot.org/eventbus/documentation/configuration/sticky-events/

订阅索引 Subscriber Index

订阅索引是3.0中的新特性,是可选项。

在3.0中由于使用了注解,比起使用反射来遍历方法的2.4版本逊色不少。但开启索引后性能远远超出旧版本。 看作者放出的图

EventBus性能对比
EventBus性能对比

既然使用索引后那么叼,那就看看怎么使用索引

注意项

  • 只有@Subscribe 可以被索引,必须是 public修饰
  • 不能再内部类中

使用 apt插件的方式

  • 顶级 build.gradle 中加入
代码语言:javascript
复制

buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
  • 再module的build.gradle 中使用 apt插件
代码语言:javascript
复制
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
  • module的build.gradle 添加依赖
代码语言:javascript
复制
dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
  • module 的 build.gradle 配置参数 ,这里写自己的包名
代码语言:javascript
复制
apt {
    arguments {
        eventBusIndex "com.example.myapp.MyEventBusIndex"
    }
}

使用索引

编译过后 会生成 MyEventBusIndex类,没有生成就多编译几遍

代码语言:javascript
复制
EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();

将索引配置到默认实例中

代码语言:javascript
复制
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
// Now the default instance uses the given index. Use it like this:
EventBus eventBus = EventBus.getDefault();

还可以添加多个不同的library中索引

代码语言:javascript
复制
EventBus eventBus = EventBus.builder()
    .addIndex(new MyEventBusAppIndex())
    .addIndex(new MyEventBusLibIndex()).build();

官网指南 http://greenrobot.org/eventbus/documentation/subscriber-index/

混淆 ProGuard

代码语言:javascript
复制
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

官网指南 http://greenrobot.org/eventbus/documentation/proguard/

AsyncExecutor

懒得翻译了,直接看吧 http://greenrobot.org/eventbus/documentation/asyncexecutor/

参考

感谢各位大神的分享

Demo地址: https://github.com/sky-mxc/AndroidDemo/tree/master/event

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 脑图
  • 概述
  • 基本使用
    • 添加依赖
      • 定义事件
        • 订阅
        • 交付线程 Delivery Threads (ThreadMode)
        • 优先级及事件取消 Priorities and Event Cancellation
        • 配置 Configuration
        • 粘性事件 Sticky Events
        • 订阅索引 Subscriber Index
        • 混淆 ProGuard
        • AsyncExecutor
        • 参考
        相关产品与服务
        事件总线
        腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档