读源码-EventBus源码解析

1-注册

1.1-核心

注册主要原理就是EventBus的三个map变量的注册:

  • subscriptionsByEventType | EventType为key,Subscription列表为Value
  • typesBySubscriber | 注册对象subscriber为key,EventType列表为Value
  • stickyEvents | EventType为key,Event对象为Value

字段说明:

字段 说明
EventType 事件类型,即@Subscribe注解的订阅方法的第一个参数对应的Class对象
Subscription 封装了订阅对象subscriber及订阅方法SubscriberMethod
SubscriberMethod 封装了订阅对象的订阅方法的相关信息,即@Subscribe注解参数及注解的方法信息
subscriber 注册对象,例如在MainActivty注册即为MainActivity的实例对象
Event 事件对象,即@Subscribe注解的订阅方法的第一个入参实参对象

1.2-注册具体源码

EventBus.getDefault().register(this);开始,this传入的是当前注册类的Activity对象

/**
 * EventBus.register方法
 */
public void register(Object subscriber) {
   
        //@1.获取对象类对应的Class对象
        Class<?> subscriberClass = subscriber.getClass();
        //@2.通过反射获取Class对象中注解的方法列表
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
   
            //@5.遍历获取的目标方法列表,并注册
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
   
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

@2.findSubscriberMethods方法获取Class对象中@Subscribe注解的方法列表。subscriberMethodFinder是EventBus的成员变量具体实现

//SubscriberMethodFinder.findSubscriberMethods方法
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
   
        //先读缓存
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
   
            return subscriberMethods;
        }
        //ignoreGeneratedIndex默认为false,若自定义EventBusBuilder则为ture
        if (ignoreGeneratedIndex) {
   
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
   
            //@3.通过反射获取Class文件的带注解方法
            subscriberMethods = findUsingInfo(subscriberClass);
        }
        if (subscriberMethods.isEmpty()) {
   
            //注册类没有@Subscriber注解,抛出异常
            throw new EventBusException("Subscriber " + subscriberClass
                    + " and its super classes have no public methods with the @Subscribe annotation");
        } else {
   
            //更新缓存
            METHOD_CACHE.put(subscriberClass, subscriberMethods);
            return subscriberMethods;
        }
    }

@3.通过反射获取Class文件的带注解方法。

//SubscriberMethodFinder.findUsingInfo方法
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
   
        //通过FindState来辅助查找
        FindState findState = prepareFindState();
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
   
            findState.subscriberInfo = getSubscriberInfo(findState);
            //第一次注册为null
            if (findState.subscriberInfo != null) {
   
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                for (SubscriberMethod subscriberMethod : array) {
   
                    if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
   
                        findState.subscriberMethods.add(subscriberMethod);
                    }
                }
            } else {
   
                //@4.筛选目标方法,并将目标方法相关信息封装到findState中的集合
                findUsingReflectionInSingleClass(findState);
            }
            //将findState.clazz修改为父类,到父类遍历
            findState.moveToSuperclass();
        }
        //返回findState中的SubscriberMethod列表,并释放findState
        return getMethodsAndRelease(findState);
    }

@4.findUsingReflectionInSingleClass方法

private void findUsingReflectionInSingleClass(FindState findState) {
   
        Method[] methods;
        try {
   
            // 通过反射获取Class对象的所有方法
            methods = findState.clazz.getDeclaredMethods();
        } catch (Throwable th) {
   
            。。。
        }
        //遍历所有方法,根据条件筛选出目标方法
        for (Method method : methods) {
   
            //获取方法修饰符
            int modifiers = method.getModifiers();
            //方法是public且非abstract、static等
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
   
                //获取方法的形参类型
                Class<?>[] parameterTypes = method.getParameterTypes();
                //只有一次参数
                if (parameterTypes.length == 1) {
   
                    //获取Subscribe注解类
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                    if (subscribeAnnotation != null) {
   
                        //获取订阅事件的类型
                        Class<?> eventType = parameterTypes[0];
                        //判断findState是否添加过该事件类型为key的键值对,未添加过返回true
                        if (findState.checkAdd(method, eventType)) {
   
                            //获取注解中指定的线程
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            //将订阅方法、事件类型、线程、优先级、是否支持粘性事件等封装成SubscriberMethod
                            //并添加到findState的subscriberMethods集合中
                            findState.subscriberMethods
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值