不,这只是个名字,一个代号,你可以叫,我也可以叫

最后编辑于2019年4月25日

提到事件总线我们总会想到EventBus和Otto,他们之间的区别是:
1、Otto可以使用@Produce的方式来发布事件;
2、EventBus提供了单例模式;
3、EventBus支持threadMode;
4、EventBus支持优先级;
5、EventBus支持编译时把订阅方法放到集合中等待调用合并成新的集合;
6、EventBus支持黏性事件。
今天这个吕秀才说死姬无命的故事就可以套用到黏性事件上。什么是黏性事件?先发送了事件后订阅对象,仍能触发订阅方法的事件就叫做黏性事件了。


一、先简单分析一下eventbus怎么处理普通事件的。


step1:订阅者注册,分为两步,一是查找订阅者的订阅方法,二是把方法按不同事件封装到一个集合中,并把方法按不同订阅对象封装到另一个集合中。

 stepA:查找订阅者的方法,根据用户设置的ignoreGeneratedIndex,决定是通过反射的方法来获取订阅者方法,还是通过调用编译时生成的class中的方法来获取订阅者方法。

 下面是通过反射的方法来获取订阅者方法:

 而通过编译时生成的class中的方法来获取订阅者方法,则需要用户先使用以下代码:

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
// 这里是获取一个单例
EventBus eventBus = EventBus.getDefault();

这样就把订阅者及订阅者方法SimpleSubscriberInfo放到subscriberInfoIndexs里了,如下面两张图:

 

 通过findUsingInfo()方法分两步获取到订阅者方法,一、把subscriberInfoIndexes中的信息放到SubscriberInfo中,二、从SubscriberInfo中获取订阅者方法。如下面三张图:

 

 stepB:把方法按不同事件封装到一个集合subscriptionsByEventType中,并把方法按不同订阅对象封装到另一个集合typesBySubscriber中:如下图:

 

step2:事件的发送

通过post()、postSingleEvent()、postSingleEventForEventType()、postToSubscription()、invokeSubscriber()几个方法的传递,最终事件的发送触发了订阅方法的调用,如下面几张图:

 

 

 

 

 

step3: 订阅者取消注册

分为两步,把该对象下的按事件分类的订阅从subscriptionsByEventType中移除,把该订阅对象下的订阅从typesBySubscriber中移除,如下面两张图:

 

 

 eventbus怎么处理普通事件的简易过程就讲完了(我只是想讲一个黏性事件的,结果讲了这么多,暴汗2333)。
 

二、黏性事件的处理

先发送了事件后注册订阅对象,仍能触发订阅方法的事件就叫做黏性事件了。
后注册订阅怎么还能触发呢?其实这个时候黏性事件反而成了订阅对象,当注册时就会调用黏性事件相关的订阅方法。

 

 

 

 

不,这只是个名字,一个代号,你可以叫订阅对象,我也可以叫订阅对象。

三、再举个例子

Person都有YoungState、OldState两种状态可以这么写:

public class Person {
    private State state;

    public void setState(State state) {
        this.state = state;
    }

    public void brush() {
        state.brush();
    }
}

public interface State {
    void brush();
}

public class YoungState implements State {
    @Override
    public void brush() {
        System.out.println("年轻人刷牙");
    }
}

public class OldState implements State {
    @Override
    public void brush() {
        System.out.println("老年人刷牙");
    }
}

在此基础上可以很轻松地加一个childState:

public class ChildState implements State {
    @Override
    public void brush() {
        System.out.println("小孩刷牙");
    }
}

 但是如果要你增加wash、eat、run几个方法呢,像下面这样吗?

public class Person {
    private State state;

    public void setState(State state) {
        this.state = state;
    }

    public void brush() {
        state.brush();
    }

    public void wash() {
        state.wash();
    }

    public void eat() {
        state.eat();
    }

    public void run() {
        state.run();
    }
}
public interface State {
    void brush();
    void wash();
    void eat();
    void run();
}
public class YoungState implements State {
    @Override
    public void brush() {
        System.out.println("年轻人刷牙");
    }

    @Override
    public void wash() {
        System.out.println("年轻人洗脸");
    }

    @Override
    public void eat() {
        System.out.println("年轻人吃饭");
    }

    @Override
    public void run() {
        System.out.println("年轻人跑步");
    }
}
public class OldState implements State {
    @Override
    public void brush() {
        System.out.println("老年人刷牙");
    }

    @Override
    public void wash() {
        System.out.println("老年人洗脸");
    }

    @Override
    public void eat() {
        System.out.println("老年人吃饭");
    }

    @Override
    public void run() {
        System.out.println("老年人跑步");
    }
}

但其实还可以换个角度,把brush、wash、eat、run当作一种状态:

public class Person {
    private State state;

    public void setState(State state) {
        this.state = state;
    }

    public void young() {
        state.young();
    }

    public void old() {
        state.old();
    }
}
public interface State {
    void young();
    void old();
}
public class BrushState implements State {
    @Override
    public void young() {
        System.out.println("年轻人刷牙");
    }

    @Override
    public void old() {
        System.out.println("老年人刷牙");
    }
}
public class WashState implements State {
    @Override
    public void young() {
        System.out.println("年轻人洗脸");
    }

    @Override
    public void old() {
        System.out.println("老年人洗脸");
    }
}
public class EatState implements State {
    @Override
    public void young() {
        System.out.println("年轻人吃饭");
    }

    @Override
    public void old() {
        System.out.println("老年人吃饭");
    }
}
public class RunState implements State {
    @Override
    public void young() {
        System.out.println("年轻人跑步");
    }

    @Override
    public void old() {
        System.out.println("老年人跑步");
    }
}

 不,这只是个名字,一个代号,你可以叫状态,我也可以叫状态。

四、再再举个例子

AIDL中客户端可以变为服务端,服务端也可以变为客户端,通过aidl调用远程服务 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值