android菜鸟笔记

EventBus源码解析

2019-08-23  本文已影响0人  李发糕

注册

我们平时使用eventbus要先注册,这里看一下注册的逻辑

EventBus.getDefault().register(this)
//这里我们可以看到这个EventBus是一个单例
 public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }

接下来我们看一下注册eventbus的代码

public void register(Object subscriber) {
        Class<?> subscriberClass = subscriber.getClass();//首先我们获取订阅者的Class
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);//这里通过subscriberMethodFinder来找到所有的订阅方法
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);//依次订阅
            }
        }
    }

然后我们看一下订阅方法是如何实现的

 // Must be called in synchronized block 由注释可知,这个必须是被同步调用
    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {//两个参数,一个是订阅者,一个是从订阅者中分离出来的订阅方法
        Class<?> eventType = subscriberMethod.eventType;//这有一个eventType 到底是啥呢,我们猜测是我们订阅时自己创建的event类,也就是订阅方法的参数
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);//生成一个订阅 要分清这些东西都是eventbus自己的类,和rxjava可没啥关系
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);//根据我们订阅的事件类型获取缓存的订阅 这个subscriptionsByEventType就是一个hashmap
        if (subscriptions == null) {//之前没有对此类事件订阅
            subscriptions = new CopyOnWriteArrayList<>();//生成对这个事件的订阅list
            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);//这个typesBySubscriber也是一个map,持有订阅者所订阅的event的Class
        if (subscribedEvents == null) {//之前没有的话,新建
            subscribedEvents = new ArrayList<>();
            typesBySubscriber.put(subscriber, subscribedEvents);
        }
        subscribedEvents.add(eventType);//把eventtype加进去

        if (subscriberMethod.sticky) {//这个属性 sticky 黏性 说实话 我没用过这个属性 所以等下再说
            if (eventInheritance) {
                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);
            }
        }
    }

取消注册

这里我们接着看一下取消注册的逻辑

EventBus.getDefault().unregister(this)
public synchronized void unregister(Object subscriber) {
        List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);//查到这个订阅者所订阅的所有时间类型
        if (subscribedTypes != null) {
            for (Class<?> eventType : subscribedTypes) {
                unsubscribeByEventType(subscriber, eventType);//取消注册事件
            }
            typesBySubscriber.remove(subscriber);//从map中删除这个订阅者
        } else {
            Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
        }
    }
    private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
        List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);//查找所有订阅了eventtype的订阅关系
        if (subscriptions != null) {
            int size = subscriptions.size();
            for (int i = 0; i < size; i++) {
                Subscription subscription = subscriptions.get(i);
                if (subscription.subscriber == subscriber) {//停止并移除由subscriber产生的订阅关系
                    subscription.active = false;
                    subscriptions.remove(i);
                    i--;
                    size--;
                }
            }
        }
    }

我们可以看到取消注册逻辑并不复杂,分别在两个map中移除相应的关系就可以了

分发事件

先看看简单的分发事件

public void post(Object event) {
        PostingThreadState postingState = currentPostingThreadState.get();//currentPostingThreadState是一个threadlocal,保存PostingThreadState
        //我们在这里取出当前线程的PostingThreadState
        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;//这个设置为啥呢 暂时不是很理解有什么必要
            }
        }
    }

我们先简单的看一下这个PostingThreadState

PostingThreadState
final static class PostingThreadState {
        final List<Object> eventQueue = new ArrayList<Object>();
        boolean isPosting;
        boolean isMainThread;
        Subscription subscription;
        Object event;
        boolean canceled;
    }

比较简单,不解释连招
然后看一下发送一个事件

postSingleEvent
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {//有可能会抛出异常
        Class<?> eventClass = event.getClass();//拿到事件的class
        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);
                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) {
            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) {
        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);
        }
    }

接下来我们依次进行分析

invokeSubscriber
    void invokeSubscriber(Subscription subscription, Object event) {
        try {
            subscription.subscriberMethod.method.invoke(subscription.subscriber, event);//这里可以看到了 直接反射调用
        } catch (InvocationTargetException e) {
            handleSubscriberException(subscription, event, e.getCause());//处理异常
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Unexpected exception", e);
        }
    }

然后我们看到当需要在非本线程调用的时候,采用的是***Poster.enqueue的方式,我们来看一下这是个啥

Poster

在分发事件的时候,我们用到了mainThreadPoster,backgroundPoster 和 asyncPoster,但其实点进去看看实现,根本就没有Poster这么个类或者接口,是我胡咧咧的,只是他们名字长得比较像,在这里的用途也差不多哈哈哈
这三个都是Eventbus实例持有的对象

    private final HandlerPoster mainThreadPoster;
    private final BackgroundPoster backgroundPoster;
    private final AsyncPoster asyncPoster;
    //在Eventbus构造方法里面实例化
    mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);//传入主线程Looper
    backgroundPoster = new BackgroundPoster(this);
    asyncPoster = new AsyncPoster(this);

我们分别看一下这三个'Poster'的实现

HandlerPoster

看名字猜得出,和handler有关 上源码

final class HandlerPoster extends Handler {

    private final PendingPostQueue queue;
    private final int maxMillisInsideHandleMessage;
    private final EventBus eventBus;
    private boolean handlerActive;

    HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
        super(looper);
        this.eventBus = eventBus;
        this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
        queue = new PendingPostQueue();//构造方法实例化一个队列,用于存储等待发送事件
    }

    void enqueue(Subscription subscription, Object event) {//这就是我们把事件发送给订阅者了
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);//包装成一个等待的发送
        synchronized (this) {//存加锁
            queue.enqueue(pendingPost);//把这个等待入队
            if (!handlerActive) {//这个handler是否正在运行
                handlerActive = true;//设置正在运行
                if (!sendMessage(obtainMessage())) {//发送一个消息 这个消息随便,反正这个handler就这里发送消息
                    throw new EventBusException("Could not send handler message");
                }
            }
        }
    }

    @Override
    public void handleMessage(Message msg) {//looper所在线程收到并处理消息
        boolean rescheduled = false;//是否推迟
        try {
            long started = SystemClock.uptimeMillis();//开始事件
            while (true) {//循环
                PendingPost pendingPost = queue.poll();//从等待发送事件队列中取出一个
                if (pendingPost == null) {//没了,防止存的数据还没存好取不出来,加锁等存好了再取一遍
                    synchronized (this) {
                        // Check again, this time in synchronized
                        pendingPost = queue.poll();
                        if (pendingPost == null) {//彻底没数据了,停止活动,return
                            handlerActive = false;
                            return;
                        }
                    }
                }
                eventBus.invokeSubscriber(pendingPost);//在lopper所在线程调用订阅者的方法
                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;
        }
    }
}
BackgroundPoster

后台运行 直接上代码

final class BackgroundPoster implements Runnable {//这就是一个runnable

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    private volatile boolean executorRunning;

    BackgroundPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {//入队操作
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);//包装成PendingPost
        synchronized (this) {
            queue.enqueue(pendingPost);//入队
            if (!executorRunning) {//执行器是否正在执行
                executorRunning = true;//执行
                eventBus.getExecutorService().execute(this);//这里看到,我们用eventBus持有的线程池来执行此runnable
            }
        }
    }

    @Override
    public void run() {//runnable方法, 和上面的handlerPoster差不多,有两处不同
        try {
            try {
                while (true) {
                    PendingPost pendingPost = queue.poll(1000);//1这里传参1000 暂时不知道是啥
                    if (pendingPost == null) {
                        synchronized (this) {
                            // Check again, this time in synchronized
                            pendingPost = queue.poll();
                            if (pendingPost == null) {
                                executorRunning = false;
                                return;
                            }
                        }
                    }
                    //没有限制最大事件,也不知道是啥
                    eventBus.invokeSubscriber(pendingPost);
                }
            } catch (InterruptedException e) {
                Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
            }
        } finally {
            executorRunning = false;
        }
    }

}
AsyncPoster

异步poster

class AsyncPoster implements Runnable {

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    AsyncPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);//这里可以看出来,所谓异步就是每一次订阅事件的发送都直接丢给线程池去处理
        queue.enqueue(pendingPost);
        eventBus.getExecutorService().execute(this);
    }

    @Override
    public void run() {
        PendingPost pendingPost = queue.poll();
        if(pendingPost == null) {
            throw new IllegalStateException("No pending post available");
        }
        eventBus.invokeSubscriber(pendingPost);
    }

}

好啦,截止到这里,一个比较简单的eventbus注册订阅发送事件接受事件取消注册的流程就走完了
但是前面的代码里有几个方法和类我们并没有详细的看,只是猜了猜他们是干啥的,下面先详细的看一下

按照顺序,第一个类就是SubscriberMethod了,它是在注册的时候由subscriberMethodFinder.findSubscriberMethods(subscriberClass)生成的并保存的,那我们一起看一下

SubscriberMethod

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;

    public SubscriberMethod(Method method, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) {//构造方法
        this.method = method;
        this.threadMode = threadMode;
        this.eventType = eventType;
        this.priority = priority;
        this.sticky = sticky;
    }

    @Override
    public boolean equals(Object other) {//重写equals方法
        if (other == this) {
            return true;
        } else if (other instanceof SubscriberMethod) {
            checkMethodString();//这个实际上就是使用类名+方法名+eventype类型拼接,也就是说判断这三个是否一样
            SubscriberMethod otherSubscriberMethod = (SubscriberMethod)other;
            otherSubscriberMethod.checkMethodString();
            // Don't use method.equals because of http://code.google.com/p/android/issues/detail?id=7811#c6
            return methodString.equals(otherSubscriberMethod.methodString);
        } else {
            return false;
        }
    }
    
    //使用类名+方法名+eventype类型拼接 并缓存
    private synchronized void checkMethodString() {
        if (methodString == null) {
            // Method.toString has more overhead, just take relevant parts of the method
            StringBuilder builder = new StringBuilder(64);
            builder.append(method.getDeclaringClass().getName());
            builder.append('#').append(method.getName());
            builder.append('(').append(eventType.getName());
            methodString = builder.toString();
        }
    }

    @Override
    public int hashCode() {
        return method.hashCode();
    }
}

接下来我们看看一个SubscriberMethod是怎么生成的

SubscriberMethodFinder

这个类相对来说比较重要啦,我们来看一下源码,比较多

class SubscriberMethodFinder {
    /*
     * In newer class files, compilers may add methods. Those are called bridge or synthetic methods.
     * EventBus must ignore both. There modifiers are not public but defined in the Java class file format:
     * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6-200-A.1
     */
    private static final int BRIDGE = 0x40;
    private static final int SYNTHETIC = 0x1000;

    private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;//要忽略的方法修饰符
    private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();//方法缓存hashmap

    private List<SubscriberInfoIndex> subscriberInfoIndexes;
    private final boolean strictMethodVerification;
    private final boolean ignoreGeneratedIndex;

    private static final int POOL_SIZE = 4;
    private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];//是一个findstate的空闲池
    //上面就是参数了,有好多我们都不认识,没关系,一步一步看

    SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,
                           boolean ignoreGeneratedIndex) {//这是构造方法
        this.subscriberInfoIndexes = subscriberInfoIndexes;//这个我们使用注解处理器生成的,,里面存贮了所有添加了sub注解的可用的方法和他的索引
        this.strictMethodVerification = strictMethodVerification;//是否对方法严格检查模式,这样的话不符合的方法会报错
        this.ignoreGeneratedIndex = ignoreGeneratedIndex;//是否忽略注解处理器生成的索引
    }

    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {//这里就是根据订阅者的Class类生成咱们的SubscriberMethod的方法了
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);//先看看缓存里面有没有
        if (subscriberMethods != null) {//有的话直接返回
            return subscriberMethods;
        }

        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;
        }
    }

    //先看这个,通过预先生成的索引查找
    private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        FindState findState = prepareFindState();//这里有一个FindState内部类,保存了一次查找的状态 这么说不是很清晰,继续看
        //看完了各大概,现在回来看看prepareFindState();
        findState.initForSubscriber(subscriberClass);//通过订阅者Class初始化
        while (findState.clazz != null) {//循环查找
            findState.subscriberInfo = getSubscriberInfo(findState);//查找并设置info给state
            if (findState.subscriberInfo != null) {//订阅者信息不为空
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();//生成所有的SubscriberMethod
                for (SubscriberMethod subscriberMethod : array) {
                    if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {//循环比对时都需要添加
                        findState.subscriberMethods.add(subscriberMethod);
                    }
                }
            } else {
                findUsingReflectionInSingleClass(findState);//使用反射查找
            }
            findState.moveToSuperclass();//指针移动到父类
        }
        return getMethodsAndRelease(findState);
    }

    private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {//查找完毕,
        List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);//取出subscriberMethods
        findState.recycle();//回收
        synchronized (FIND_STATE_POOL) {//放进回收池
            for (int i = 0; i < POOL_SIZE; i++) {
                if (FIND_STATE_POOL[i] == null) {
                    FIND_STATE_POOL[i] = findState;
                    break;
                }
            }
        }
        return subscriberMethods;
    }

    private FindState prepareFindState() {
        synchronized (FIND_STATE_POOL) {//从闲置池中拿一个findstate出来
            for (int i = 0; i < POOL_SIZE; i++) {
                FindState state = FIND_STATE_POOL[i];
                if (state != null) {
                    FIND_STATE_POOL[i] = null;
                    return state;
                }
            }
        }
        return new FindState();//如果没有就搞一个新的
    }

    private SubscriberInfo getSubscriberInfo(FindState findState) {
        //第一次查找的话状态里肯定没有保存subscriberInfo
        if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
            SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
            if (findState.clazz == superclassInfo.getSubscriberClass()) {
                return superclassInfo;
            }
        }
        //设置了索引
        if (subscriberInfoIndexes != null) {
            for (SubscriberInfoIndex index : subscriberInfoIndexes) {//遍历索引
                SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
                if (info != null) {
                    return info;
                }
            }
        }
        return null;
    }

    private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
        FindState findState = prepareFindState();
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
            findUsingReflectionInSingleClass(findState);
            findState.moveToSuperclass();
        }
        return getMethodsAndRelease(findState);
    }

    private void findUsingReflectionInSingleClass(FindState findState) {//使用反射查找
        Method[] methods;//方法
        try {
            // This is faster than getMethods, especially when subscribers are fat classes like Activities
            methods = findState.clazz.getDeclaredMethods();//包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法
        } catch (Throwable th) {//报错了
            // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
            methods = findState.clazz.getMethods();//这样查找的话连父类的方法都查出来了
            findState.skipSuperClasses = true;//跳过父类
        }
        for (Method method : methods) {//循环
            int modifiers = method.getModifiers();//获取修饰符
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {//不包含上面的几个修饰符
                Class<?>[] parameterTypes = method.getParameterTypes();//获取方法的所有参数
                if (parameterTypes.length == 1) {//只有一个参数
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);//是否添加了@Subscribe注解
                    if (subscribeAnnotation != null) {//添加了
                        Class<?> eventType = parameterTypes[0];//拿到参数Class
                        if (findState.checkAdd(method, eventType)) {//检查添加事件类型和对应的方法 
                            ThreadMode threadMode = subscribeAnnotation.threadMode(); //获取注解生成的线程模式
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));//添加一个SubscriberMethod进去
                        }
                    }
                } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {//如果添加了Subscribe注解并且开启了对方法的严格检查
                    String methodName = method.getDeclaringClass().getName() + "." + method.getName();//报错
                    throw new EventBusException("@Subscribe method " + methodName +
                            "must have exactly 1 parameter but has " + parameterTypes.length);
                }
            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {//如果添加了Subscribe注解并且开启了对方法的严格检查
                String methodName = method.getDeclaringClass().getName() + "." + method.getName();//报错
                throw new EventBusException(methodName +
                        " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
            }
        }
    }

    static void clearCaches() {
        METHOD_CACHE.clear();
    }

    static class FindState { //内部类 代表一个查找的状态
        final List<SubscriberMethod> subscriberMethods = new ArrayList<>();//SubscriberMethod数组
        final Map<Class, Object> anyMethodByEventType = new HashMap<>();//方法和eventType的对应集合
        final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();//订阅者的类和MethodKey的对应集合
        final StringBuilder methodKeyBuilder = new StringBuilder(128);//用于构造methodKey

        Class<?> subscriberClass;//本订阅者的类
        Class<?> clazz;//要被查找的类指针
        boolean skipSuperClasses;//是否跳过父类
        SubscriberInfo subscriberInfo;//订阅者信息 这是一个接口

        //初始化
        void initForSubscriber(Class<?> subscriberClass) {//初始化订阅者Class
            this.subscriberClass = clazz = subscriberClass;//当前类指向订阅者类
            skipSuperClasses = false;//设置默认
            subscriberInfo = null;
        }

        //回收
        void recycle() {
            subscriberMethods.clear();//清空各个数组
            anyMethodByEventType.clear();
            subscriberClassByMethodKey.clear();
            methodKeyBuilder.setLength(0);
            subscriberClass = null;
            clazz = null;
            skipSuperClasses = false;
            subscriberInfo = null;
        }

        //这个方法的代码,我对于中间的异常抛出不是很理解,在这里请教一下各位老哥,禁止这种情况的意义是啥呢?比如父类有两个方法订阅相同的event,子类重写了这两个方法并也添加了@Sub注解,就会报异常了,但是和重写或者相同的event关系不大,看下面的代码就知道只有子类父类订阅同event以及重写的方法数量特定的情况下才会触发这个异常
        boolean checkAdd(Method method, Class<?> eventType) {
            // 2 level check: 1st level with event type only (fast), 2nd level with complete signature when required.
            //判断两次 
            // Usually a subscriber doesn't have methods listening to the same event type.//通常一个订阅者不会有多个方法订阅同一个event
            Object existing = anyMethodByEventType.put(eventType, method);//之前是否有方法订阅此事件
            if (existing == null) {//没有,返回true
                return true;
            } else {
                //之前有方法订阅这个事件了 这就说明在订阅者中出现了多个方法都订阅了此事件
                if (existing instanceof Method) {//这里进行判断 如果是method,说明里面的method
                    if (!checkAddWithMethodSignature((Method) existing, eventType)) {
                        // Paranoia check//顾明思意,这是一个'妄想'的检查,理论上不会出现这种情况 所以我们先看看看这到底检查的是个啥
                        throw new IllegalStateException();//报错
                    }
                    // Put any non-Method object to "consume" the existing Method
                    anyMethodByEventType.put(eventType, this);//
                }
                return checkAddWithMethodSignature(method, eventType);
            }
        }
66
        private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {//这个方法的作用是把method和eventtype保存起来,如果之前保存过一样说明一个是父类的方法,
            //一个是子类的方法,这种情况下 我们选择保留子类的方法
            //如果新的是子类或者以前没有保存过,返回true 反之返回false
            methodKeyBuilder.setLength(0);
            methodKeyBuilder.append(method.getName());
            methodKeyBuilder.append('>').append(eventType.getName());

            String methodKey = methodKeyBuilder.toString();//methodKey = "methodName>eventTypeName"
            Class<?> methodClass = method.getDeclaringClass();//获取声明这个方法的class
            Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);//看看之前有没有保存这种方法名相同参数也相同的方法?
            if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
                //如果没有,说明是不同名的方法,返回true
                //或者已有的方法是新方法的父类调用的 返回true
                // Only add if not already found in a sub class
                return true;
            } else {
                // Revert the put, old class is further down the class hierarchy
                subscriberClassByMethodKey.put(methodKey, methodClassOld);//返回false
                return false;
            }
        }

        void moveToSuperclass() {//进去父类继续寻找
            if (skipSuperClasses) {//是否跳过父类
                clazz = null;
            } else {
                clazz = clazz.getSuperclass();//clazz为父类
                String clazzName = clazz.getName();
                /** Skip system classes, this just degrades performance. */
                if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") || clazzName.startsWith("android.")) {//父类为系统类,跳过
                    clazz = null;
                }
            }
        }
    }

}

黏性

前面看到这个就表示没见过,现在先把它怼了
因为我没用过TT,所以直接去百度了 有位老哥是这么解释的

所谓的黏性事件,就是指发送了该事件之后再订阅者依然能够接收到的事件。
使用黏性事件的时候有两个地方需要做些修改。一个是订阅事件的地方,
另一个是发布事件的地方,调用EventBus的postSticky方法来发布事件

好,这样理解就比较清晰了,因为黏性事件是先发送,后订阅,那我们看源码也按照这个顺序来

postSticky
public void postSticky(Object event) {
        synchronized (stickyEvents) {
            stickyEvents.put(event.getClass(), event);
        }
        // Should be posted after it is putted, in case the subscriber wants to remove immediately
        post(event);
    }

这一段代码可以说很简单了=,=就是把我们的黏性事件加了入了一个map里面存了起来,这里我们也就知道了,当发送多个类型的黏性事件时,后注册的订阅者只会触发最后一个
下面就可以说一说注册的情况了

注册

上面之前已经上了代码,我们这里就只选和黏性有关的东西

if (subscriberMethod.sticky) {//这里,注册方法的时候判断这是不是粘性的
            if (eventInheritance) {//event事件继承是否开启
                //暂时省略这部分代码
            } else {
                Object stickyEvent = stickyEvents.get(eventType);//取出相应的粘性事件
                checkPostStickyEventToSubscription(newSubscription, stickyEvent);//检查是否发送这个粘性事件给当前订阅
            }
        }
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
        if (stickyEvent != null) {//event 存在
            // If the subscriber is trying to abort the event, it will fail (event is not tracked in posting state)
            // --> Strange corner case, which we don't take care of here.
            postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());//这里直接发送这个黏性事件
        }
    }

可见这个黏性比较简单,只是在发送的时候存储起来,等待有人注册的时候看看是否需要发送,如果需要就发送
下面我们来看看上面省略的eventInheritance

eventInheritance

这个是干什么的呢?
我从网上搜来一段描述

如果post(A),A extends B implements C,D implements C
那么onEvent(A)、onEvent(B)、onEvent(C)会被调用,onEvent(D)不会被调用

很清晰啊,下面我就上相关代码,看看是如何实现的

if (eventInheritance) {//这里是发送非黏性event的代码块,上面有出现过,只不过我们忽略了这个开启了event继承模式情况下里面的逻辑
            List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);//获取这个event的所有父类及接口
            int countTypes = eventTypes.size();
            for (int h = 0; h < countTypes; h++) {//依次发送
                Class<?> clazz = eventTypes.get(h);
                subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);//发送事件,只要有一次成功就成功
            }
        } else {//不开启event继承模式
            subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);//发送事件
        }

lookupAllEventTypes方法:

/** Looks up all Class objects including super classes and interfaces. Should also work for interfaces. */
    private static List<Class<?>> lookupAllEventTypes(Class<?> eventClass) {
        synchronized (eventTypesCache) {
            List<Class<?>> eventTypes = eventTypesCache.get(eventClass);//这是一个eventClass对应其父类及所有的接口的缓存,第一次查询肯定是空的
            if (eventTypes == null) {//没有缓存
                eventTypes = new ArrayList<>();
                Class<?> clazz = eventClass;//先指向当前clazz
                while (clazz != null) {//不为空
                    eventTypes.add(clazz);//放入list
                    addInterfaces(eventTypes, clazz.getInterfaces());//把所有的接口也放进去
                    clazz = clazz.getSuperclass();//指向父类,继续查找添加
                }
                eventTypesCache.put(eventClass, eventTypes);//加入缓存
            }
            return eventTypes;//返回
        }
    }

addInterfaces方法:

 /** Recurses through super interfaces. */
    static void addInterfaces(List<Class<?>> eventTypes, Class<?>[] interfaces) {
        for (Class<?> interfaceClass : interfaces) {
            if (!eventTypes.contains(interfaceClass)) {//如果list中不存在
                eventTypes.add(interfaceClass);//加入
                addInterfaces(eventTypes, interfaceClass.getInterfaces());//递归加入
            }
        }
    }

下面我们再看看黏性事件的情况

if (subscriberMethod.sticky) {//这是订阅者注册的时候
            if (eventInheritance) {//开启了event继承接收
                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);
            }
        }

注解处理器

@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")//要处理的注解
@SupportedOptions(value = {"eventBusIndex", "verbose"})//要处理的属性 第一个就是在build中设置的生成的文件名,第二个'冗余模式',是否打印输出信息
public class EventBusAnnotationProcessor extends AbstractProcessor {
    public static final String OPTION_EVENT_BUS_INDEX = "eventBusIndex";
    public static final String OPTION_VERBOSE = "verbose";

    /** Found subscriber methods for a class (without superclasses). */
    private final ListMap<TypeElement, ExecutableElement> methodsByClass = new ListMap<>();//一个map 方法和class的对应
    //
    private final Set<TypeElement> classesToSkip = new HashSet<>();

    private boolean writerRoundDone;
    private int round;
    private boolean verbose;

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();//支持的最低版本
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        Messager messager = processingEnv.getMessager();//用于打印log的对象
        try {
            String index = processingEnv.getOptions().get(OPTION_EVENT_BUS_INDEX);//文件名
            if (index == null) {
                messager.printMessage(Diagnostic.Kind.ERROR, "No option " + OPTION_EVENT_BUS_INDEX +
                        " passed to annotation processor");
                return false;
            }
            verbose = Boolean.parseBoolean(processingEnv.getOptions().get(OPTION_VERBOSE));//这个暂时不知道是啥
            int lastPeriod = index.lastIndexOf('.');//截取文件夹名
            String indexPackage = lastPeriod != -1 ? index.substring(0, lastPeriod) : null;

            round++;//计数加一
            if (verbose) {//打印信息
                messager.printMessage(Diagnostic.Kind.NOTE, "Processing round " + round + ", new annotations: " +
                        !annotations.isEmpty() + ", processingOver: " + env.processingOver());
            }
            if (env.processingOver()) {//这个暂时不懂是啥 todo
                if (!annotations.isEmpty()) {
                    messager.printMessage(Diagnostic.Kind.ERROR,
                            "Unexpected processing state: annotations still available after processing over");
                    return false;
                }
            }
            if (annotations.isEmpty()) {//empty
                return false;
            }

            if (writerRoundDone) {//是否已经写完了
                messager.printMessage(Diagnostic.Kind.ERROR,
                        "Unexpected processing state: annotations still available after writing.");
            }
            collectSubscribers(annotations, env, messager);//收集Subscribers
            checkForSubscribersToSkip(messager, indexPackage);//检查Subscriber应不应该被跳过

            if (!methodsByClass.isEmpty()) {//不为空,写入文件
                createInfoIndexFile(index);
            } else {
                messager.printMessage(Diagnostic.Kind.WARNING, "No @Subscribe annotations found");
            }
            writerRoundDone = true;
        } catch (RuntimeException e) {
            // IntelliJ does not handle exceptions nicely, so log and print a message
            e.printStackTrace();
            messager.printMessage(Diagnostic.Kind.ERROR, "Unexpected error in EventBusAnnotationProcessor: " + e);
        }
        return true;
    }
//剩下的方法没有写什么注释了,感兴趣的老哥可以自己看下//
    private void collectSubscribers(Set<? extends TypeElement> annotations, RoundEnvironment env, Messager messager) {
        for (TypeElement annotation : annotations) {//循环注解
            Set<? extends Element> elements = env.getElementsAnnotatedWith(annotation);//获取这个注解对应的元素
            for (Element element : elements) {
                if (element instanceof ExecutableElement) {//如果是方法
                    ExecutableElement method = (ExecutableElement) element;
                    if (checkHasNoErrors(method, messager)) {//检查有没有错误
                        TypeElement classElement = (TypeElement) method.getEnclosingElement();//获取声明这个方法的类
                        methodsByClass.putElement(classElement, method);//放进去
                    }
                } else {//不是方法,报错
                    messager.printMessage(Diagnostic.Kind.ERROR, "@Subscribe is only valid for methods", element);
                }
            }
        }
    }

    private boolean checkHasNoErrors(ExecutableElement element, Messager messager) {
        if (element.getModifiers().contains(Modifier.STATIC)) {//不能是静态方法
            messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must not be static", element);
            return false;
        }

        if (!element.getModifiers().contains(Modifier.PUBLIC)) {//必须是public方法
            messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must be public", element);
            return false;
        }

        List<? extends VariableElement> parameters = ((ExecutableElement) element).getParameters();//必须有且只有一个参数
        if (parameters.size() != 1) {
            messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must have exactly 1 parameter", element);
            return false;
        }
        return true;
    }

    /**
     * 如果索引不可见其类或任何涉及的事件类,则应跳过订阅者类。
     */
    private void checkForSubscribersToSkip(Messager messager, String myPackage) {
        for (TypeElement skipCandidate : methodsByClass.keySet()) {//循环所有的查到的类
            TypeElement subscriberClass = skipCandidate;
            while (subscriberClass != null) {
                if (!isVisible(myPackage, subscriberClass)) {//这个类相对目标包不可见
                    boolean added = classesToSkip.add(skipCandidate);//添加进去
                    if (added) {//打印log
                        String msg;
                        if (subscriberClass.equals(skipCandidate)) {
                            msg = "Falling back to reflection because class is not public";
                        } else {
                            msg = "Falling back to reflection because " + skipCandidate +
                                    " has a non-public super class";
                        }
                        messager.printMessage(Diagnostic.Kind.NOTE, msg, subscriberClass);
                    }
                    break;
                }
                List<ExecutableElement> methods = methodsByClass.get(subscriberClass);//找到所有对应的方法
                if (methods != null) {
                    for (ExecutableElement method : methods) {//循环
                        String skipReason = null;
                        VariableElement param = method.getParameters().get(0);//参数对象
                        TypeMirror typeMirror = getParamTypeMirror(param, messager);//
                        if (!(typeMirror instanceof DeclaredType) ||
                                !(((DeclaredType) typeMirror).asElement() instanceof TypeElement)) {
                            skipReason = "event type cannot be processed";
                        }
                        if (skipReason == null) {
                            TypeElement eventTypeElement = (TypeElement) ((DeclaredType) typeMirror).asElement();
                            if (!isVisible(myPackage, eventTypeElement)) {
                                skipReason = "event type is not public";
                            }
                        }
                        if (skipReason != null) {
                            boolean added = classesToSkip.add(skipCandidate);
                            if (added) {
                                String msg = "Falling back to reflection because " + skipReason;
                                if (!subscriberClass.equals(skipCandidate)) {
                                    msg += " (found in super class for " + skipCandidate + ")";
                                }
                                messager.printMessage(Diagnostic.Kind.NOTE, msg, param);
                            }
                            break;
                        }
                    }
                }
                subscriberClass = getSuperclass(subscriberClass);
            }
        }
    }

    private TypeMirror getParamTypeMirror(VariableElement param, Messager messager) {
        TypeMirror typeMirror = param.asType();//获取参数类型
        // Check for generic type
        if (typeMirror instanceof TypeVariable) {
            TypeMirror upperBound = ((TypeVariable) typeMirror).getUpperBound();
            if (upperBound instanceof DeclaredType) {
                if (messager != null) {
                    messager.printMessage(Diagnostic.Kind.NOTE, "Using upper bound type " + upperBound +
                            " for generic parameter", param);
                }
                typeMirror = upperBound;
            }
        }
        return typeMirror;
    }

    private TypeElement getSuperclass(TypeElement type) {
        if (type.getSuperclass().getKind() == TypeKind.DECLARED) {
            TypeElement superclass = (TypeElement) processingEnv.getTypeUtils().asElement(type.getSuperclass());
            String name = superclass.getQualifiedName().toString();
            if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
                // Skip system classes, this just degrades performance
                return null;
            } else {
                return superclass;
            }
        } else {
            return null;
        }
    }

    private String getClassString(TypeElement typeElement, String myPackage) {
        PackageElement packageElement = getPackageElement(typeElement);
        String packageString = packageElement.getQualifiedName().toString();
        String className = typeElement.getQualifiedName().toString();
        if (packageString != null && !packageString.isEmpty()) {
            if (packageString.equals(myPackage)) {
                className = cutPackage(myPackage, className);
            } else if (packageString.equals("java.lang")) {
                className = typeElement.getSimpleName().toString();
            }
        }
        return className;
    }

    private String cutPackage(String paket, String className) {
        if (className.startsWith(paket + '.')) {
            // Don't use TypeElement.getSimpleName, it doesn't work for us with inner classes
            return className.substring(paket.length() + 1);
        } else {
            // Paranoia
            throw new IllegalStateException("Mismatching " + paket + " vs. " + className);
        }
    }

    private PackageElement getPackageElement(TypeElement subscriberClass) {
        Element candidate = subscriberClass.getEnclosingElement();
        while (!(candidate instanceof PackageElement)) {
            candidate = candidate.getEnclosingElement();
        }
        return (PackageElement) candidate;
    }

    private void writeCreateSubscriberMethods(BufferedWriter writer, List<ExecutableElement> methods,
                                              String callPrefix, String myPackage) throws IOException {
        for (ExecutableElement method : methods) {
            List<? extends VariableElement> parameters = method.getParameters();
            TypeMirror paramType = getParamTypeMirror(parameters.get(0), null);
            TypeElement paramElement = (TypeElement) processingEnv.getTypeUtils().asElement(paramType);
            String methodName = method.getSimpleName().toString();
            String eventClass = getClassString(paramElement, myPackage) + ".class";

            Subscribe subscribe = method.getAnnotation(Subscribe.class);
            List<String> parts = new ArrayList<>();
            parts.add(callPrefix + "(\"" + methodName + "\",");
            String lineEnd = "),";
            if (subscribe.priority() == 0 && !subscribe.sticky()) {
                if (subscribe.threadMode() == ThreadMode.POSTING) {
                    parts.add(eventClass + lineEnd);
                } else {
                    parts.add(eventClass + ",");
                    parts.add("ThreadMode." + subscribe.threadMode().name() + lineEnd);
                }
            } else {
                parts.add(eventClass + ",");
                parts.add("ThreadMode." + subscribe.threadMode().name() + ",");
                parts.add(subscribe.priority() + ",");
                parts.add(subscribe.sticky() + lineEnd);
            }
            writeLine(writer, 3, parts.toArray(new String[parts.size()]));

            if (verbose) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Indexed @Subscribe at " +
                        method.getEnclosingElement().getSimpleName() + "." + methodName +
                        "(" + paramElement.getSimpleName() + ")");
            }

        }
    }

    private void createInfoIndexFile(String index) {
        BufferedWriter writer = null;
        try {
            JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(index);
            int period = index.lastIndexOf('.');
            String myPackage = period > 0 ? index.substring(0, period) : null;
            String clazz = index.substring(period + 1);
            writer = new BufferedWriter(sourceFile.openWriter());
            if (myPackage != null) {
                writer.write("package " + myPackage + ";\n\n");
            }
            writer.write("import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;\n");
            writer.write("import org.greenrobot.eventbus.meta.SubscriberMethodInfo;\n");
            writer.write("import org.greenrobot.eventbus.meta.SubscriberInfo;\n");
            writer.write("import org.greenrobot.eventbus.meta.SubscriberInfoIndex;\n\n");
            writer.write("import org.greenrobot.eventbus.ThreadMode;\n\n");
            writer.write("import java.util.HashMap;\n");
            writer.write("import java.util.Map;\n\n");
            writer.write("/** This class is generated by EventBus, do not edit. */\n");
            writer.write("public class " + clazz + " implements SubscriberInfoIndex {\n");
            writer.write("    private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;\n\n");
            writer.write("    static {\n");
            writer.write("        SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();\n\n");
            writeIndexLines(writer, myPackage);
            writer.write("    }\n\n");
            writer.write("    private static void putIndex(SubscriberInfo info) {\n");
            writer.write("        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);\n");
            writer.write("    }\n\n");
            writer.write("    @Override\n");
            writer.write("    public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {\n");
            writer.write("        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);\n");
            writer.write("        if (info != null) {\n");
            writer.write("            return info;\n");
            writer.write("        } else {\n");
            writer.write("            return null;\n");
            writer.write("        }\n");
            writer.write("    }\n");
            writer.write("}\n");
        } catch (IOException e) {
            throw new RuntimeException("Could not write source for " + index, e);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    //Silent
                }
            }
        }
    }

    private void writeIndexLines(BufferedWriter writer, String myPackage) throws IOException {
        for (TypeElement subscriberTypeElement : methodsByClass.keySet()) {
            if (classesToSkip.contains(subscriberTypeElement)) {
                continue;
            }

            String subscriberClass = getClassString(subscriberTypeElement, myPackage);
            if (isVisible(myPackage, subscriberTypeElement)) {
                writeLine(writer, 2,
                        "putIndex(new SimpleSubscriberInfo(" + subscriberClass + ".class,",
                        "true,", "new SubscriberMethodInfo[] {");
                List<ExecutableElement> methods = methodsByClass.get(subscriberTypeElement);
                writeCreateSubscriberMethods(writer, methods, "new SubscriberMethodInfo", myPackage);
                writer.write("        }));\n\n");
            } else {
                writer.write("        // Subscriber not visible to index: " + subscriberClass + "\n");
            }
        }
    }

    private boolean isVisible(String myPackage, TypeElement typeElement) {
        Set<Modifier> modifiers = typeElement.getModifiers();
        boolean visible;
        if (modifiers.contains(Modifier.PUBLIC)) {
            visible = true;
        } else if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.PROTECTED)) {
            visible = false;
        } else {
            String subscriberPackage = getPackageElement(typeElement).getQualifiedName().toString();
            if (myPackage == null) {
                visible = subscriberPackage.length() == 0;
            } else {
                visible = myPackage.equals(subscriberPackage);
            }
        }
        return visible;
    }

    private void writeLine(BufferedWriter writer, int indentLevel, String... parts) throws IOException {
        writeLine(writer, indentLevel, 2, parts);
    }

    private void writeLine(BufferedWriter writer, int indentLevel, int indentLevelIncrease, String... parts)
            throws IOException {
        writeIndent(writer, indentLevel);
        int len = indentLevel * 4;
        for (int i = 0; i < parts.length; i++) {
            String part = parts[i];
            if (i != 0) {
                if (len + part.length() > 118) {
                    writer.write("\n");
                    if (indentLevel < 12) {
                        indentLevel += indentLevelIncrease;
                    }
                    writeIndent(writer, indentLevel);
                    len = indentLevel * 4;
                } else {
                    writer.write(" ");
                }
            }
            writer.write(part);
            len += part.length();
        }
        writer.write("\n");
    }

    private void writeIndent(BufferedWriter writer, int indentLevel) throws IOException {
        for (int i = 0; i < indentLevel; i++) {
            writer.write("    ");
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读