EventBus框架库代码走读

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

【工匠若水 】

本篇继续接上一篇,阅读上一篇EventBus使用之基础

背景

开始分析EventBus前可以下看下EventBus开源框架的工程目录结构:

从上图可以发现,其实EventBus的代码量不是很大,还是很方便入手分析的。

开始分析

通过上一篇基础使用可以发现,使用EventBus框架第一步是得到EventBus实例,那我们就从EventBus类文件的getDefault()方法开始分析。如下:

EventBus getDefault() {if (defaultInstance == null) {synchronized (EventBus.class) {if (defaultInstance == null) {defaultInstance = new EventBus();}}}return defaultInstance;}

这里就是设计模式的一个单例模式运用,使用了双重判断的方式,防止并发的问题,还能极大的提高效率。接着往下看EventBus()构造方法:

public EventBus() {this(DEFAULT_BUILDER);}EventBus(EventBusBuilder builder) {subscriptionsByEventType = new HashMap<Class<?>, CopyOnWriteArrayList<Subscription>>();typesBySubscriber = new HashMap<Object, List<Class<?>>>();stickyEvents = new ConcurrentHashMap<Class<?>, Object>();mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);backgroundPoster = new BackgroundPoster(this);asyncPoster = new AsyncPoster(this);subscriberMethodFinder = new SubscriberMethodFinder(builder.skipMethodVerificationForClasses);logSubscriberExceptions = builder.logSubscriberExceptions;logNoSubscriberMessages = builder.logNoSubscriberMessages;sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;sendNoSubscriberEvent = builder.sendNoSubscriberEvent;throwSubscriberException = builder.throwSubscriberException;eventInheritance = builder.eventInheritance;executorService = builder.executorService;}

这里的构造方法EventBus(EventBusBuilder builder)使用了建造者模式给EventBus设置一些基本参数标志。这里使用了DEFAULT_BUILDER,也即默认参数。

到这里一个默认的单例模式的EventBus对象实例获取完成。通过这段代码可以发现,我们也可以通过 EventBusBuilder或者EventBus的构造函数新建一个EventBus实例,但是每个新建的EventBus发布和订阅事件都是相互隔离的。

接着继续停留在EventBus类分析,可以看到该类的主要职责就是负责所有对外暴露的API。

按照上一篇的使用例子顺序来看,得到EventBus实例后需要在开始处调运register方法,结束处调运unregister方法,所以我们从register方法开始分析:

(Object subscriber) {register(subscriber, false, 0);}(Object subscriber, int priority) {register(subscriber, false, priority);}(Object subscriber) {register(subscriber, true, 0);}(Object subscriber, int priority) {register(subscriber, true, priority);}(Object subscriber, boolean sticky, int priority) {List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriber.getClass());for (SubscriberMethod subscriberMethod : subscriberMethods) {subscribe(subscriber, subscriberMethod, sticky, priority);}}

可以看到EventBus类提供了四个register方法,但是最终都调运了register(Object subscriber, boolean sticky, int priority)方法。

register(Object subscriber, boolean sticky, int priority)方法的三个参数含义如下:

由此可以看出register(Object subscriber),registerSticky(Object subscriber)的默认优先级都是0,其他的register方法可自定义优先级。同理register的方法默认都是不粘粘性的事件,registerSticky的方法没人都是粘粘性的事件。

继续看register(Object subscriber, boolean sticky, int priority)方法,可以发现其中首先执行了List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriber.getClass());语句,这句话就是调运SubscriberMethodFinder类的findSubscriberMethods方法,传入了subscriber 的class,返回一个List<SubscriberMethod>。如下:

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {String key = subscriberClass.getName();List<SubscriberMethod> subscriberMethods;synchronized (methodCache) {subscriberMethods = methodCache.get(key);}if (subscriberMethods != null) {return subscriberMethods;}subscriberMethods = new ArrayList<SubscriberMethod>();Class<?> clazz = subscriberClass;HashSet<String> eventTypesFound = new HashSet<String>();StringBuilder methodKeyBuilder = new StringBuilder();while (clazz != null) {String name = clazz.getName();if (name.startsWith(“java.”) || name.startsWith(“javax.”) || name.startsWith(“android.”)) {// Skip system classes, this just degrades performancebreak;}// Starting with EventBus 2.2 we enforced methods to be public (might change with annotations again)Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {String methodName = method.getName();if (methodName.startsWith(ON_EVENT_METHOD_NAME)) {int modifiers = method.getModifiers();if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {Class<?>[] parameterTypes = method.getParameterTypes();if (parameterTypes.length == 1) {String modifierString = methodName.substring(ON_EVENT_METHOD_NAME.length());ThreadMode threadMode;if (modifierString.length() == 0) {threadMode = ThreadMode.PostThread;} else if (modifierString.equals(“MainThread”)) {threadMode = ThreadMode.MainThread;} else if (modifierString.equals(“BackgroundThread”)) {threadMode = ThreadMode.BackgroundThread;} else if (modifierString.equals(“Async”)) {threadMode = ThreadMode.Async;} else {if (skipMethodVerificationForClasses.containsKey(clazz)) {continue;} else {throw new EventBusException(“Illegal onEvent method, check for typos: ” + method);}}Class<?> eventType = parameterTypes[0];methodKeyBuilder.setLength(0);methodKeyBuilder.append(methodName);methodKeyBuilder.append(‘>’).append(eventType.getName());String methodKey = methodKeyBuilder.toString();if (eventTypesFound.add(methodKey)) {// Only add if not already found in a sub classsubscriberMethods.add(new SubscriberMethod(method, threadMode, eventType));}}} else if (!skipMethodVerificationForClasses.containsKey(clazz)) {Log.d(EventBus.TAG, “Skipping method (not public, static or abstract): ” + clazz + “.”+ methodName);}}}clazz = clazz.getSuperclass();}if (subscriberMethods.isEmpty()) {throw new EventBusException(“Subscriber ” + subscriberClass + ” has no public methods called “+ ON_EVENT_METHOD_NAME);} else {synchronized (methodCache) {methodCache.put(key, subscriberMethods);}return subscriberMethods;}}为你的快乐而快乐的是朋友,为你的难过而难过的才是你的知己。

EventBus框架库代码走读

相关文章:

你感兴趣的文章:

标签云: