安卓EventBus的使用

Androidstudio使用步骤:

一、导入依赖 compile 'org.greenrobot:eventbus:3.0.0'

二、使用

1、定义事件。事件是纯Java对象,没有其他的特殊要求

public class MessageEvent {

    public final String message;

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

2、准备订阅者。订阅者需要实现在事件发布时将被调用的事件处理方法(也称为“订阅方法”)。 这些订阅方法将用@Subscribe注释定义。 订阅者还需要向总线注册和注销。 只有订阅者注册后,他们才会收到事件。 在Android的在活动和片段中,通常应该根据其生命周期进行注册。 对于大多数情况下在onStart中注册,在onStop中销毁就OK了。

// 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);
}

 

3、发布事件。在代码的任意地方发布事件,所有与当前事件匹配且注册过的订阅者都将会收到事件。

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

三、传递线程

EventBus可以为你处理线程:事件可以发布在不同于发布线程的线程中。事件可以发布在和发布线程不同的线程里。一个普遍的场景就是处理UI的变化。在Android系统中,UI更改必须在UI(主)线程中完成。另一方面,网络或者任何耗时的任务,都不允许在主线程中执行。EventBus帮助你处理这些任务并且与UI线程同步(无需深入了解线程转换,使用AsyncTask等)。

在EventBus中,你可以通过使用四个ThreadMode中的一个来定义将调用事件处理方法的线程。

ThreadMode: POSTING

订阅者将会在事件发布的线程中被调用。这是默认模式。事件的传递是同步完成的,一旦事件发布完成,所有的订阅者都将会被调用。由于完全避免了线程切换,这种模式的开销是最小的。所以,针对那些不需要主线程并且能在很短时间内完成的简单任务,我们推荐使用这种模式。这种模式下的事件处理方法必须快速返回,避免阻塞发布事件的线程,因为这个线程有可能是主线程。 


ThreadMode: MAIN

订阅者将在Android的主线程(有时称为UI线程)中调用。 如果发布线程是主线程,则将直接调用事件处理方法(与ThreadMode.POSTING描述的同步)。 使用此模式的事件处理程序必须快速返回,以避免阻塞主线程。 

ThreadMode: BACKGROUND

订阅者将在后台线程中调用。 如果发布线程不是主线程,事件处理程序方法将直接在发布线程中调用。 如果发布线程是主线程,EventBus使用单个后台线程来按顺序传递所有事件。 使用此模式的事件处理方法应尽快返回以避免阻塞后台线程。 

ThreadMode: ASYNC

事件处理方法在单独的线程中调用。 这个线程总是独立于发布线程和主线程。 这种模式下,发布事件不会等待事件处理方法的执行结果。 如果事件处理方法的执行需要一些时间,则应该使用此模式,如网络访问。 避免同时触发大量长时间运行的异步处理方法以限制并发线程的数量。 EventBus使用线程池来有效地重用已完成任务的线程。 

四、粘性事件

一些事件携带在事件发布之后感兴趣的信息。 例如,事件表示某些初始化完成。 或者如果您有一些传感器或位置数据,并且想要保持最近的值。 而不是实现自己的缓存,你可以使用粘性事件。 所以EventBus保持内存中某个类型的最后一个粘性事件。 然后粘性事件可以传递给订阅者或明确地查询。 因此,您不需要任何特殊的逻辑来考虑已有的数据

粘性示例

下面表示,一个粘性事件发布了一段时间以前:

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));

现在一个新的活动开始。 在注册期间,所有粘性订阅者方法将立即获得先前发布的粘性事件:

@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();
}

手动获取和删除粘性事件

如你所见,最后一个粘性事件在注册时自动传递给匹配的订阅者。 但有时手动检查粘性事件可能会更方便。 另外,可能需要移除(消费)粘性事件才能使得它们不再被递送。 例:

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
}

方法removeStickyEvent是重载的:当你传入类时,它将返回先前持有的粘性事件。 使用这个变化,我们可以改进前面的例子:

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

五、优先级和事件取消

尽管EventBus的大多数用例不需要优先级或事件取消,但在某些特殊情况下它们可能派上用场。 例如,如果应用处于前台,则事件可以触发一些UI逻辑,但如果应用当前对用户不可见,则事件可以不同地反应。

订阅者优先级

你可以通过在注册期间为订阅者提供优先级来更改事件传递的顺序。

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

在相同的传递线程(ThreadMode)中,较高优先级的订阅者将在其他优先级较低的订阅者之前接收事件。 默认优先级为0。 
注意:优先级不影响不同线程模式的订阅者之间的传递顺序!

取消事件传送

你可以通过从订阅者的事件处理方法调用cancelEventDelivery(Object event)来取消事件传递过程。 任何其他活动传送将被取消,后续订阅者将不会收到活动。

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

事件通常由更高优先级的订阅者取消。 取消仅限于在发布线程(ThreadMode.PostThread)中运行的事件处理方法。

六、二次封装

1、工具类

public class EventUtils {

    /**
     * 注册EventBus
     * @param object
     */
    public static void registerEventBus(Object object){
        if (object != null){
            if (!EventBus.getDefault().isRegistered(object)){
                EventBus.getDefault().register(object);
            }
        }
    }

    /**
     * 解除EventBus
     * @param object
     */
    public static void unRegisterEventBus(Object object){
        if (object != null){
            if (EventBus.getDefault().isRegistered(object)){
                EventBus.getDefault().unregister(object);
            }
        }
    }

    /**
     * 判断自己的事件类型
     * @param type
     * @param center
     * @return
     */
    public static boolean isMyEvent(String type,EventCenter center){
        return StringUtils.isEquals(type,center.type);
    }

    public static void post(EventCenter eventCenter){
        EventBus.getDefault().post(eventCenter);
    }

    public static<T> void postData(String type,T t){
        post(new EventCenter<T>(type,t));
    }

    public static void postDefult(String type){
        post(new EventCenter<String>(type,""));
    }

}

2、事件类

public class EventCenter<T>{

    public T data;//消息数据
    public String type;//消息类型
    public String what;//不确定消息类型
    public HashMap<String,Object> dataMap;

    public EventCenter(String type, T t){
        this.type = type;
        this.data = t;
    }

    public EventCenter(String type, String what, T t){
        this.type = type;
        this.data = t;
        this.what = what;
    }

    public void put(String key,Object value){
        if (!StringUtils.isEmpty(key) && value != null){
            if (dataMap == null){
                dataMap = new HashMap<>();
            }
            dataMap.put(key, value);
        }
    }

    public Object get(String key){
        if (!StringUtils.isEmpty(key) && dataMap != null && dataMap.containsKey(key)){
            return dataMap.get(key);
        }else {
            return null;
        }
    }

}

3、使用

①注册/反注册事件(Base类中)

 @Override
    protected void onStart() {
        super.onStart();
        //注册Eventbug
        if (isRegisterEventBus()) {
            EventUtils.registerEventBus(this);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        //解除Eventbus
        if (isRegisterEventBus()) {
            EventUtils.unRegisterEventBus(this);
        }
    }

    /**
     * 是否需要注册EventBus
     *
     * @return
     */
    public boolean isRegisterEventBus() {
        return false;
    }

②基类使用

 @Override
    public boolean isRegisterEventBus() {
        return true;
    }

    /**
     * 处理EventBus事件
     *
     * @param eventCenter
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void handleEvent(EventCenter<Object> eventCenter) {
        if (EventUtils.isMyEvent(TYPE1, eventCenter)) {
           //处理TYPE1事件 
            Object data = eventCenter.data;//结果为123,(下文传递)

        } else if (EventUtils.isMyEvent(TYPE2, eventCenter)) {
            //处理TYPE2事件
        }
    }

③发送事件

EventUtils.postData(TYPE1,"123);
EventUtils.postDefult(TYPE2);

七、混淆配置

-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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值