利用反射仿写一个简单的EventBus

什么是EventBus

EventBus是基于事件总站的方式接收Publisher发布的消息,然后回调各个订阅者的相关订阅函数,这样可以有效的解耦发布者和订阅者在 Android中的事件传递关系。

相关对象

Event:就是Publisher发布的某一种类型对象。
EventBus:事件总站,用于存贮订阅者对某个事件类型的注册信息。
Subscriber:对某种类型的对象进行订阅,也就是在EventBus中进行注册。Publisher发布此类对象时,EventBus 会执行Subscriber的一些列 onEvent 函数。订阅者通过 register 接口订阅某个事件类型,unregister 接口退订。
Publisher:发布某Event对象,通过 post 方法发布Event。

流程图

这里写图片描述
大概的情况介绍完了,下面通过例子来介绍:
Subscriber是一个简单的Activity,在onCreate中注册,在onDestroy中注销

public class DemoActivity extends BaseActivity implements DataListener,View.OnClickListener {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
        MyBus.get().register(this);
    }

    @Override
    public void initView() {
        button = (Button)findViewById(R.id.buton);
    }
    @Override
    public void initOnClickListener() {
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.buton:
                startActivity(new Intent(this,SonActivity.class));
                break;
        }
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();
    }
    public void onEvent(String postStr){
        button.setText(postStr);
    }
}

代码很简单,就是注册和反注册,然后里面的注册函数为onEvent,参数时String类型的。
下面看看注册函数是什么样的

public void register(Object subscriber) {
        Class<?> clazz = subscriber.getClass();
        Method[] methods = clazz.getMethods();
        for (Method m : methods) {
            String name = m.getName();
            if (name.startsWith("onEvent")) {
                SubInfo subInfo = new SubInfo();
                subInfo.subscriber = subscriber;
                subInfo.method = m;
                if (isExist(m)) {
                    isRegister(m).subscriberList.add(subInfo);
                } else {
                    Class<?>[] params = m.getParameterTypes();
                    Subscription subscription = new Subscription();
                    subscription.clazz = params[0];
                    subscription.subscriberList = new ArrayList<>();
                    subscription.subscriberList.add(subInfo);
                    classInfoList.add(subscription);
                }
            }
        }
    }
    rivate Subscription isRegister(Method m) {
        Subscription subscription = new Subscription();
        Class<?>[] params = m.getParameterTypes();
        if (isExist(m)) {
            for (Subscription subs : classInfoList) {
                if (subs.clazz == params[0]) {
                    subscription = subs;
                    break;
                }
            }
        }
        return subscription;
    }

    private boolean isExist(Method m) {
        boolean isExist = false;
        Class<?>[] params = m.getParameterTypes();
        for (Subscription subs : classInfoList) {
            if (subs.clazz == params[0]) {
                isExist = true;
                break;
            }
        }
        return isExist;
    }

利用反射原理得到Subscriber以onEvent开头的注册函数以及第一个参数,如果这个参数类型的已经存在了就把原来以及注册过这个参数的对象拿出来,加到订阅者list中去,如果不存在,声明一个这个类型的注册对象,并将这个订阅者加到这个类型的订阅者list中去,

public class Subscription {
    Class<?> clazz;
    List<SubInfo> subscriberList;
}

下面是注销函数

 public void unregister(String name, Class<?>[] params) {
        for (Subscription subs : classInfoList) {
            if (subs.clazz == params[0]) {
                for (int i = 0; i < subs.subscriberList.size(); i++) {
                    if (subs.subscriberList.get(i).method.equals(name)) {
                        subs.subscriberList.remove(i);
                    }
                }
                break;
            }
        }
    }


    public void unRegister(Object subscriber) {
        Class<?> clazz = subscriber.getClass();
        Method[] methods = clazz.getMethods();
        for (Method m : methods) {
            String name = m.getName();
            Class<?>[] params = m.getParameterTypes();
            if (name.startsWith("onEvent")) {
                unregister(name, params);
            }
        }
    }

然后发布
MyBus.get().post(“post success”);
再看看是怎么样实现发布函数执行的

 public void post(Object event) {
        Class<?> clazz = event.getClass();
        Subscription subscription = null;
        for(int i=0 ;i< classInfoList.size();i++){
            if(classInfoList.get(i).clazz == clazz){
                subscription = classInfoList.get(i);
            }
        }
        if(subscription != null) {
            postSub(subscription,event);
        }
    }
    private void postSub(Subscription subscription,Object event){
        List<SubInfo> subscriptionList = subscription.subscriberList;
        for(int i = 0;i<subscriptionList.size();i++){
            SubInfo subInfo = subscriptionList.get(i);
            MyPostThread.post(subInfo,event);
        }
    }

看看MyPostThread这个类

public class MyPostThread{
    MyPostThread() {
    }
    public static void post(SubInfo subInfo,Object event){
        MyBus.get().invoke(subInfo,event, subInfo.method);
    }
}

最后还是利用反射原理的相关函数完成注册者的注册函数调用

 public void invoke(final SubInfo sub, final Object event,Method m){
        try {
            m.invoke(sub.subscriber,event);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

Ok,代码到这里就完成了,有兴趣的同学可以试一下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值