EventBus框架核心原理

EventBus 框架解耦和核心原理(事件总线,订阅,取消订阅,解耦,根据自己看源码的理解手写一个简洁版的EventBus)
下面是EventBus类的核心代码
 /**
         *  注入对象(将对象添加到事件总线中去)
         * @param obj
         */
        public void regist(Object obj) {
            List<SubscribeMethod> subscribeMethods = mCacheMap.get(obj);
            if (subscribeMethods == null) {
                subscribeMethods = findSubscribeMethod(obj);
                mCacheMap.put(obj, subscribeMethods);
            }
        }
 /**
         * 根据注入对象把带有Subsribe注解的方法封装到事件总线中去
         * @param obj
         * @return
         */
        private List<SubscribeMethod> findSubscribeMethod(Object obj) {
            List<SubscribeMethod> list = new ArrayList<>();
            Class<?> aClass = obj.getClass();
            while (aClass != null) {
                //获取当前类声明的方法
                Method[] methods = aClass.getDeclaredMethods();
                for (Method method : methods) {
                    //获取定义的注解类型
                    Subscribe subscribe = method.getAnnotation(Subscribe.class);
                    if (subscribe == null) {
                        continue;
                    }
                     //获取方法中的参数类型
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    //如果参数类型长度不是1就给用户抛异常(传递多个参数可以放到MessageEvent对象中)
                    if (parameterTypes.length != 1) {
                        throw new IllegalArgumentException("EventBus params only one");
                    }
                    //获取注解模式
                    ThreadMode threadMode = subscribe.threadMode();
                    //创建事件总线中的实体类
                    SubscribeMethod subscribeMethod = new SubscribeMethod(method, threadMode, parameterTypes[0]);
                    list.add(subscribeMethod);

                }
                aClass = aClass.getSuperclass();
            }

            return list;
        }
        
        /**
         *  被观察者发出的事件
         * @param type
         */
        public void post(Object type) {
            Set<Object> keySet = mCacheMap.keySet();
            Iterator<Object> iterator = keySet.iterator();
            while (iterator.hasNext()) {
                Object obj = iterator.next();
                //获取到事件总线中对应的注入对象中对应的事件
                List<SubscribeMethod> subscribeMethods = mCacheMap.get(obj);
                  for (SubscribeMethod subscribeMethod : subscribeMethods) {
                    //判断参数类型是否是继承关系
                    if (subscribeMethod.getType().isAssignableFrom(type.getClass())) {
                        invoke(subscribeMethod, obj, type);
                    }
                }
            }
        }
private void invoke(SubscribeMethod subscribeMethod, Object obj, Object type) {
            Method method = subscribeMethod.getMethod();
            //如果是主线程  invoke  ThreadMode == ThreadMode.MAIN 的方法
            if (isMainThread()){
                if (subscribeMethod.getThreadMode() == ThreadMode.MAIN){
                    try {
                        method.invoke(obj, type);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
                 } else{
                //如果是主线程  invoke  ThreadMode == ThreadMode.BACKGOUND 的方法
                if (subscribeMethod.getThreadMode() == ThreadMode.BACKGOUND){
                    try {
                        method.invoke(obj, type);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
 /**
         *  注销  把事件总线中的注入对象对应的事件清空  意味着收不到EventBus发送出来的消息了
         */
        public void unRegist(Object obj) {
            mCacheMap.remove(obj);
        }

        /**
         * 判断当前线程是否是主线程
         * @return
         */
        public boolean isMainThread() {
            return Looper.getMainLooper() == Looper.myLooper();
        }
自定义注解类(ThraedMode就是一个枚举)
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
	//默认是主线程(要可以手动设置成子线程或者其他的模式)
    ThreadMode threadMode() default ThreadMode.MAIN;
}

事件总线中的实体类(主要封装了Method,TheadMode,Type(参数类型))
 private Method method;
    private ThreadMode threadMode;
    private Class<?> type;

    public SubscribeMethod(Method method, ThreadMode threadMode, Class<?> type) {
        this.method = method;
        this.threadMode = threadMode;
        this.type = type;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public ThreadMode getThreadMode() {
        return threadMode;
    }

    public void setThreadMode(ThreadMode threadMode) {
        this.threadMode = threadMode;
    }

    public Class<?> getType() {
        return type;
    }

    public void setType(Class<?> type) {
        this.type = type;
    }
下面是发送和接收
 //Aclass
 @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event){
        Log.d("====>","主线程:"+event.toString());
    }

    @Subscribe(threadMode = ThreadMode.BACKGOUND)
    public void onMessageEvent1(MessageEvent event){
        Log.d("====>","子线程:"+event.toString());
    }
-------------------------------
//Bclass
 public void main(View view) {
        EventBus.getDefault().post(new MessageEvent("罗大佑","唱歌"));
    }

    public void sub(View view) {
        new Thread(){
            @Override
            public void run() {
                super.run();
                EventBus.getDefault().post(new MessageEvent("科比","打篮球"));
            }
        }.start();
    }

运行结果如下
2019-10-10 10:15:00.834 6614-6614/com.example.eventbuspro D/====1>: MessageEvent{name='罗大佑', hobby='唱歌'}
2019-10-10 10:15:02.202 6614-6664/com.example.eventbuspro D/====2>: MessageEvent{name='科比', hobby='打篮球'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值