【无标题】

概念

EventBus是一种用于Android的事件发布-订阅的事件总线。由三个角色构成:Publisher(发布者)、Event(事件)和Subscriber(订阅者)。



线程模型

  • POSTING:默认,表示事件处理函数的线程跟发布事件的线程在同一个线程。
  • MAIN:表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
  • BACKGROUND:表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
  • ASYNC:表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。



源码

getDefault()

	//双重校验并加锁的单例模式创建EventBus实例。
	public static EventBus getDefault() {
    	if (defaultInstance == null) {
	      	synchronized (EventBus.class) {
            	if (defaultInstance == null) {
                	defaultInstance = new EventBus();/** EventBus无参构造函数 */
            	}
        	}
    	}
    	return defaultInstance;
	}
  • EventBus无参构造函数:
	private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();/** EventBusBuilder构造函数 */
	
    public EventBus() {
        this(DEFAULT_BUILDER); /** EventBus有参构造函数 */
    }
  • EventBusBuilder构造函数:
    EventBusBuilder() {
    }
  • EventBus有参构造函数:
	//同时创建一个EventBusBuilder对象对EventBus进行初始化。
	//其中有三个比较重要的集合和一个SubscriberMethodFinder对象。
    EventBus(EventBusBuilder builder) {
        logger = builder.getLogger();
        subscriptionsByEventType = new HashMap<>();//事件订阅类型集合一😊
        typesBySubscriber = new HashMap<>();//订阅者类型的集合😊
        stickyEvents = new ConcurrentHashMap<>();//联系集合😊
        mainThreadSupport = builder.getMainThreadSupport();
        mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;//主线程初始化操作
        backgroundPoster = new BackgroundPoster(this);//子线程初始化操作
        asyncPoster = new AsyncPoster(this);//异步线程初始化
        indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;//得到订阅信息的数量
        subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
                builder.strictMethodVerification, builder.ignoreGeneratedIndex);//查找订阅的方法😊
        logSubscriberExceptions = builder.logSubscriberExceptions;//订阅的日志异常
        logNoSubscriberMessages = builder.logNoSubscriberMessages;//没有订阅消息日志
        sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;//订阅者发送事件异常
        sendNoSubscriberEvent = builder.sendNoSubscriberEvent;//订阅者没有发送事件
        throwSubscriberException = builder.throwSubscriberException;//订阅者抛出异常
        eventInheritance = builder.eventInheritance;
        executorService = builder.executorService;//执行者服务
    }

regist()

	public void register(Object subscriber) {
		//首先通过反射获取到订阅者的Class对象。
        Class<?> subscriberClass = subscriber.getClass();
        //通过SubscriberMethodFinder对象获取订阅者中所有订阅的事件集合。
        //它先从缓存中获取,如果缓存中有,直接返回;
        //如果缓存中没有,通过反射的方式去遍历订阅者内部被注解的方法,将这些方法放入到集合中进行返回。
        List<SubscriberMethod> subscriberMethods = /** SubscriberMethod类源码 */
        	subscriberMethodFinder.findSubscriberMethods(subscriberClass); /** findSubscriberMethods()方法获取订阅者中所有订阅的事件集合 */
        //同步操作,遍历获取的集合,将订阅者和事件进行绑定。
        
        //在绑定之后会判断绑定的事件是否是粘性事件,
        //如果是粘性事件,直接调用postToSubscription方法,将之前发送的粘性事件发送给订阅者。
        
        //其实这也很好理解,如果在粘性事件发送之前注册的订阅者,当发送粘性事件时,会接收到该事件;
        //如果是粘性事件发送之后注册的订阅者,同样也能接收到事件。
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);/** subscribe()方法绑定订阅者和事件 */
            }
        }
    }

  • findSubscriberMethods()方法获取订阅者中所有订阅的事件集合
	List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
		//首先从缓存中读取 
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }

		//是否忽略注解器生成的MyEventBusIndex类
        if (ignoreGeneratedIndex) {
        	//利用反射来获取订阅类中的订阅方法信息
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
        	//从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
            subscriberMethods = findUsingInfo(subscriberClass);
        }
        if (subscriberMethods.isEmpty()) {
            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;
        }
    }
  • SubscriberMethod类源码:
public class SubscriberMethod {
    final Method method;//方法
    final ThreadMode threadMode;//执行线程
    final Class<?> eventType;//接收的事件类型
    final int priority;//优先级
    final boolean sticky;
    /** Used for efficient comparison */
    String methodString;
}
  • subscribe()方法绑定订阅者和事件:
	//参数:订阅者,订阅方法集
	private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
		//获取订阅方法的参数类型
        Class<?> eventType = subscriberMethod.eventType;
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        //根据订阅的事件类型获取所有的订阅者
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        //将订阅者添加到subscriptionsByEventType集合中
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);
        } else {
            if (subscriptions.contains(newSubscription)) {
                throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                        + eventType);
            }
        }

		//根据优先级,将订阅者插入到指定的位置
        int size = subscriptions.size();
        for (int i = 0; i <= size; i++) {
            if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
                subscriptions.add(i, newSubscription);
                break;
            }
        }

		//获取订阅者所有订阅的事件类型
        List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList<>();
            typesBySubscriber.put(subscriber, subscribedEvents);
        }
        //将该事件类型添加到typesBySubscriber中
        subscribedEvents.add(eventType);

		//如果接收sticky事件,立即分发sticky事件
        if (subscriberMethod.sticky) {
            if (eventInheritance) {
                // Existing sticky events of all subclasses of eventType have to be considered.
                // Note: Iterating over all events may be inefficient with lots of sticky events,
                // thus data structure should be changed to allow a more efficient lookup
                // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
                Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
                for (Map.Entry<Class<?>, Object> entry : entries) {
                    Class<?> candidateEventType = entry.getKey();
                    if (eventType.isAssignableFrom(candidateEventType)) {
                        Object stickyEvent = entry.getValue();
                        checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                    }
                }
            } else {
                Object stickyEvent = stickyEvents.get(eventType);
                checkPostStickyEventToSubscription(newSubscription, stickyEvent);
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值