EventBus 源码分析

基本使用

//注册EventBus
EventBus.getDefault().register(this);
//发送事件
EventBus.getDefault().post(new FirstEvent("nihao-->"));
//接受事件回调方法
@Subscribe
public void onMainEvent(FirstEvent eventBean)
{
	Toast.makeText(this,"FirstEvent--> "+eventBean.msg,Toast.LENGTH_SHORT).show();
	Log.d(TAG,"FirstEvent ");
}
//反注册EventBus
EventBus.getDefault().unregister(this);


源码分析


//DCL 获取EventBus单例
public static EventBus getDefault()
{
	if (defaultInstance == null) {
		synchronized (EventBus.class) {
			if (defaultInstance == null) {
				defaultInstance = new EventBus();
			}
		}
	}
	return defaultInstance;
}

private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
//eventTypesCache 以eventType 为key,该类的接口与继承父类为value,主要是为了将所有关联的事件关系保存在表里面,进行事件继承的消息通知
private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();
//以事件类型为 key ,订阅列表 Subscription为value的一张map,
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
//以订阅者Subscriber 为key,以事件列表为value的map表
private final Map<Object, List<Class<?>>> typesBySubscriber;
//粘贴性事件表
private final Map<Class<?>, Object> stickyEvents;

public EventBus()
{
	this(DEFAULT_BUILDER);
}

EventBus(EventBusBuilder builder)
{
	subscriptionsByEventType = new HashMap<>();
	typesBySubscriber = new HashMap<>();
	stickyEvents = new ConcurrentHashMap<>();
  //主线程 post
	mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
  //后台线程 post
	backgroundPoster = new BackgroundPoster(this);
  //异步线程 post
	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;
}


** EventBus#register 注销方法 **

//看看比较重要的注册方法

public void register(Object subscriber)
{
  //得到订阅者的类
	Class<?> subscriberClass = subscriber.getClass();
  //从subscriberMethodFinder集合里面去查找订阅该类里面的方法
	List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
	synchronized (this) {
  //遍历进行订阅
	for (SubscriberMethod subscriberMethod : subscriberMethods) {
			subscribe(subscriber, subscriberMethod);
		}
	}
}

** EventBus#subscribe **

// Must be called in synchronized block
//这里其实就是通过类型EventType 放 Subscription 集合
// 通过 subscriber 放类型 EventType 集合
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod)
{
	Class<?> eventType = subscriberMethod.eventType;
	//Subscription二次封装了订阅者对象和 subscriberMethod,并且put到 CopyOnWriteArrayList 集合。
	Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
	//CopyOnWriteArrayList 适用于多线程并发操作,集合中存储的对象是已订阅者划分的
	//每个相同的eventType对应一个CopyOnWriteArrayList 集合
	CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
	if (subscriptions == null) {
		subscriptions = new CopyOnWriteArrayList<>();
		subscriptionsByEventType.put(eventType, subscriptions);
	} else {
		//subscriptions 不为null代表有相同订阅事件类型的 Subscription 对象。
		//如果在相同订阅事件类型前提下,订阅对象和订阅方法完全一样,就抛异常。Subscription对象中有具体的 equals()判断方法
		if (subscriptions.contains(newSubscription)) {
			throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
			                            + eventType);
		}
	}

	//根据注释中的 priority 值大小对相同订阅事件类型的 newSubscription 进行排序,
	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;
		}
	}
	//typesBySubscriber 每个订阅对象对应一个集合
	List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
	if (subscribedEvents == null) {
		subscribedEvents = new ArrayList<>();
		typesBySubscriber.put(subscriber, subscribedEvents);
	}
	subscribedEvents.add(eventType);
	Log.d("wangjian", "subscriber = "+subscriber.getClass().getName()+", eventType = "+eventType.getName()+", subscribedEvents = "+subscribedEvents.size());
	//判断方法注释中sticky值是否为true,默认为false
	if (subscriberMethod.sticky) {
		//只有在注册之前调用了postSticky()方法,下面的post才会有效
		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>).

			//如果class A extends B,A 事件为粘性事件,参数为 A 和 B订阅方法都能能收到 A 对象的消息。
			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 {
			//eventInheritance = false情况,参数为 B 的注释方法是收不到消息的。
			Object stickyEvent = stickyEvents.get(eventType);
			checkPostStickyEventToSubscription(newSubscription, stickyEvent);
		}
	}
}

** SubscriberMethodFinder#findSubscriberMethods **

private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        //先从METHOD_CACHE缓存中取出列表,没有的话就通过对象参数找出对应的订阅方法列表。
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
        //通过默认的方式实例化EventBus,ignoreGeneratedIndex为false
        if (ignoreGeneratedIndex) {
            //利用反射方法得到订阅方法列表
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
            //这个比较难,暂时还没学习。利用编译时查找订阅事件的方式完成,高端
            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;
        }
    }

** EventBus#unregister 反注销方法 **


public synchronized void unregister(Object subscriber)
{
	//通过subscriber 拿到 subscribedTypes 列表
	List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
	if (subscribedTypes != null) {
		for (Class<?> eventType : subscribedTypes) {
			//遍历解除绑定
			unsubscribeByEventType(subscriber, eventType);
		}
		// 从 typesBySubscriber 表中移除掉
		typesBySubscriber.remove(subscriber);
	} else {
		Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
	}
}

//解除 key:eventType  Value:subscriber 的Map表里面的元素
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
			 List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
			 if (subscriptions != null) {
					 int size = subscriptions.size();
					 for (int i = 0; i < size; i++) {
							 Subscription subscription = subscriptions.get(i);
							 if (subscription.subscriber == subscriber) {
									 subscription.active = false;
									 subscriptions.remove(i);
									 i--;
									 size--;
							 }
					 }
			 }
	 }

** EventBus#post 发送事件方法 **

//post方法
public void post(Object event)
{
	PostingThreadState postingState = currentPostingThreadState.get();
	List<Object> eventQueue = postingState.eventQueue;
	eventQueue.add(event);

	if (!postingState.isPosting) {
		//是否是主线程
		postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
		//是否正在发送标志
		postingState.isPosting = true;
		if (postingState.canceled) {
			throw new EventBusException("Internal error. Abort state was not reset");
		}
		try {
			while (!eventQueue.isEmpty()) {
				//如果事件队列不为空,进行事件发送,
				postSingleEvent(eventQueue.remove(0), postingState);
			}
		}
		finally {
			postingState.isPosting = false;
			postingState.isMainThread = false;
		}
	}
}
//postSingleEvent 方法
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
	Class<?> eventClass = event.getClass();
	boolean subscriptionFound = false;
	//是否支持事件继承关系
	if (eventInheritance) {
		//查找所有订阅事件及其超类的超接口
		List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
		int countTypes = eventTypes.size();
		for (int h = 0; h < countTypes; h++) {
			Class<?> clazz = eventTypes.get(h);
			//将这些查找到的class与subscriptionsByEventType集合中的key进行匹配,并发送
			subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
		}
	} else {
		//发送事件
		subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
	}
	if (!subscriptionFound) {
		if (logNoSubscriberMessages) {
			Log.d(TAG, "No subscribers registered for event " + eventClass);
		}
		if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
		          eventClass != SubscriberExceptionEvent.class) {
			post(new NoSubscriberEvent(this, event));
		}
	}
}
//postSingleEventForEventType
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass)
{
	CopyOnWriteArrayList<Subscription> subscriptions;
	synchronized (this) {
		//从subscriptionsByEventType集合中查找是否存在这个事件
		subscriptions = subscriptionsByEventType.get(eventClass);
	}
	if (subscriptions != null && !subscriptions.isEmpty()) {
		//遍历发送
	for (Subscription subscription : subscriptions) {
			postingState.event = event;
			postingState.subscription = subscription;
			boolean aborted = false;
			try {
				//发送给订阅者
				postToSubscription(subscription, event, postingState.isMainThread);
				aborted = postingState.canceled;
			}
			finally {
				postingState.event = null;
				postingState.subscription = null;
				postingState.canceled = false;
			}
			if (aborted) {
				break;
			}
		}
		return true;
	}
	return false;
}
//postToSubscription 主要是线程选择后通过反射调用和异步执行在对应的线程
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread)
{
	//通过 threadMode 确定应该在哪条线程中发送消息
	switch (subscription.subscriberMethod.threadMode) {
	case POSTING:
		invokeSubscriber(subscription, event);
		break;
	case MAIN:
		//如果当前线程是主线程,直接反射调用注册方法 如果不是放到主线程去异步执行
		if (isMainThread) {
			invokeSubscriber(subscription, event);
		} else {
			mainThreadPoster.enqueue(subscription, event);
		}
		break;
	case BACKGROUND:
		if (isMainThread) {
			backgroundPoster.enqueue(subscription, event);
		} else {
			invokeSubscriber(subscription, event);
		}
		break;
	case ASYNC:
		asyncPoster.enqueue(subscription, event);
		break;
	default:
		throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
	}
}

** 看看主线程的切换执行 HandlerPoster **

//Looper为主线程 最大消息处理时间是10ms
HandlerPoster mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
//HandlerPoster 是继承 Handler  主线程消息处理
class HandlerPoster extends Handler
// 主线程任务执行队列
private final PendingPostQueue queue;
//加入主线程 执行
void enqueue(Subscription subscription, Object event)
{
	//将subscription 和 消息事件对象封装到 PendingPost 中。
	PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
	synchronized (this) {
		//加入队列
		queue.enqueue(pendingPost);
		if (!handlerActive) {
			handlerActive = true;
			//发送消息通知
			if (!sendMessage(obtainMessage())) {
				throw new EventBusException("Could not send handler message");
			}
		}
	}
}

//消息的处理
@Override
public void handleMessage(Message msg)
{
	boolean rescheduled = false;
	try {
		long started = SystemClock.uptimeMillis();
		//死循环 循环去除队列数据 
		while (true) {
			//从队列中取出 PendingPost 通过eventBus 对象直接发送。
			//每次取出一个 header,会将下一个待发送 PendingPost 赋值给 header,直到发送完
			//从执行队列里面去除一个post对象
			PendingPost pendingPost = queue.poll();
			if (pendingPost == null) {
				synchronized (this) {
					// Check again, this time in synchronized
					pendingPost = queue.poll();
					if (pendingPost == null) {
						handlerActive = false;
						return;
					}
				}
			}
			//在主线程里面进行反射调用对应的方法
			eventBus.invokeSubscriber(pendingPost);
			//在规定时间内没发送完,退出本次任务,重新执行handleMessage()接着发送
			long timeInMethod = SystemClock.uptimeMillis() - started;
			if (timeInMethod >= maxMillisInsideHandleMessage) {
				if (!sendMessage(obtainMessage())) {
					throw new EventBusException("Could not send handler message");
				}
				rescheduled = true;
				//退出
				return;
			}
		}
	}
	finally {
		handlerActive = rescheduled;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章