EventBus 源码分析

EventBus分析

EventBus执行流程分析

EventBus基本使用

//在Activity里使用EventBus

@Override
protected void onStart() {
    super.onStart();
    //注册
    EventBus.getDefault().register(this);
}

public void btnClick(View v) {
    //发布事件
    EventBus.getDefault().post(new MessageEvent<String>(100, "hello 这是一条普通事件"));
}

//订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent<String> event) {
    if (event.getCode() == 100) {
        tv_msg.setText(event.getData());
    }
}

//订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent2<String> event) {
    if (event.getCode() == 100) {
        tv_msg.setText(event.getData());
    }
}

@Override
protected void onStop() {
    super.onStop();
    //反注册
    EventBus.getDefault().unregister(this);
}

事件流向

EventBus事件流向

订阅者和订阅事件关系

上面的代码里,订阅者subscriber是Activity,监听了两个事件MessageEventMessageEvent2,当发布事件后,会收到2个数据。

订阅者通过register()方法注册,一个订阅者可以对应多个事件,通过一个Map结构维护。

private final Map<Object, List<Class<?>>> typesBySubscriber;

订阅者和订阅事件关系

订阅事件和订阅者关系

在Android中,一个事件可能被多个subscriber订阅,当发布事件时,会查找所有订阅了该事件的subscriber,并调用其中的event方法,通过一个Map结构维护。

private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;

订阅事件和订阅者关系

粘性事件关系

发布的粘性事件会将事件类型和事件保存在一个Map结构中,注册时订阅消息会从stickyEvents取出消息并执行。

private final Map<Class<?>, Object> stickyEvents;

粘性事件

EventBus源码分析

EventBus核心属性

//key为订阅者对象,value为订阅事件类型集合(Event类型)
private final Map<Object, List<Class<?>>> typesBySubscriber;

//订阅信息类,包含订阅者对象和订阅方法
final class Subscription {
    final Object subscriber;
    final SubscriberMethod subscriberMethod;
}

//key为事件类型,value为Subscription对象
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;

//key为订阅者的class对象,value为订阅者中的所有订阅方法
private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();

注册

EventBus#getDefault()

//单例模式,获取EventBus对象
public static EventBus getDefault() {
    EventBus instance = defaultInstance;
    if (instance == null) {
        synchronized (EventBus.class) {
            instance = EventBus.defaultInstance;
            if (instance == null) {
                instance = EventBus.defaultInstance = new EventBus();
            }
        }
    }
    return instance;
}

EventBus#register()

//注册订阅者
public void register(Object subscriber) {
    //获取的class对象
    Class<?> subscriberClass = subscriber.getClass();

    //获得注册类的所有订阅方法
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);

    //遍历订阅方法
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            //关联注册类和订阅方法
            subscribe(subscriber, subscriberMethod);
        }
    }
}

SubscriberMethodFinder#findSubscriberMethods()

//获取所有订阅方法
//必须是@Subscribe注解,public修饰,一个参数
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
    //先从缓存中获取订阅方法
    List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
    if (subscriberMethods != null) {
        return subscriberMethods;
    }

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

SubscriberMethodFinder#findUsingInfo()

//若findState缓存订阅方法信息,则使用findState里的缓存,否则调用findUsingReflectionInSingleClass()获取订阅方法信息
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
    //获取一个存储对象findState
    FindState findState = prepareFindState();
    //findState存储订阅者的class对象
    findState.initForSubscriber(subscriberClass);
    
    //findState.clazz就是subscriberClass
    while (findState.clazz != null) {
        findState.subscriberInfo = getSubscriberInfo(findState);
        
        //第一次注册时,findState.subscriberInfo为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 {
            //执行此处
            findUsingReflectionInSingleClass(findState);
        }
        //需要遍历父类,修改findState.clazz为subscriberClass的父类的class对象
        findState.moveToSuperclass();
    }
    
    //返回findState中保存的订阅方法,并释放findState
    return getMethodsAndRelease(findState);
}

SubscriberMethodFinder#findUsingReflectionInSingleClass()

//通过反射获取订阅方法的信息
private void findUsingReflectionInSingleClass(FindState findState) {
    Method[] methods;
    try {
        //获取订阅者中的所有方法
        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();

            //判断参数个数,只能有1个参数
            if (parameterTypes.length == 1) {

                //获取方法有@Subscribe的注解
                Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);

                //若方法有@Subscribe注解,则就是订阅者中的订阅方法
                if (subscribeAnnotation != null) {
                    //获取订阅方法中的第一个参数类型,依旧是订阅的事件类型
                    Class<?> eventType = parameterTypes[0];
                    //checkAdd用于判断FindState是否添加过该事件
                    if (findState.checkAdd(method, eventType)) {
                        //获取线程模式
                        ThreadMode threadMode = subscribeAnnotation.threadMode();
                        //将订阅方法中的信息(如:订阅方法、事件类型、线程模式、优先级、粘性事件等)封装成SubscriberMethod对象,并保存到到findState中的subscriberMethods集合里
                        findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                    }
                }

            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                //参数个数超过1个时,抛出异常
                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)) {
            //方法的修饰符不是public时,抛出异常
            String methodName = method.getDeclaringClass().getName() + "." + method.getName();
            throw new EventBusException(methodName + " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
        }
    }
}

SubscriberMethodFinder#getMethodsAndRelease()

private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
    //获取findState中的subscriberMethods
    List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.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;
}

EventBus#subscribe()

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    //获取订阅方法的事件类型
    Class<?> eventType = subscriberMethod.eventType;

    //将订阅者和订阅方法封装成一个Subscription对象
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);

    //subscriptionsByEventType是HashMap结构,key为事件类型,value为Subscription对象
    //获取该事件的所有订阅者信息
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);

    //若不存在
    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);
        }
    }

    //添加newSubscription对象到subscriptions集合中
    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是HashMap结构,key为订阅者对象,value为事件集合
    //获取该订阅者的事件集合
    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    if (subscribedEvents == null) {
        subscribedEvents = new ArrayList<>();
        typesBySubscriber.put(subscriber, subscribedEvents);
    }
    //添加到集合中
    subscribedEvents.add(eventType);

    //是否支持粘性事件
    if (subscriberMethod.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#unregister()

public synchronized void unregister(Object subscriber) {
    //获取当前订阅者的所有事件类型集合
    List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
    //若集合不为null
    if (subscribedTypes != null) {
        //遍历集合,获取订阅事件的类型
        for (Class<?> eventType : subscribedTypes) {
            //解除事件订阅
            unsubscribeByEventType(subscriber, eventType);
        }
        //删除订阅者信息
        typesBySubscriber.remove(subscriber);
    } else {
        logger.log(Level.WARNING, "Subscriber to unregister was not registered  before:"+subscriber.getClass());
    }
}

EventBus#unsubscribeByEventType()

//解除事件订阅
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
    //根据当前事件类型,获取订阅者集合
    List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    //若集合不为null
    if (subscriptions != null) {
        int size = subscriptions.size();
        //遍历订阅者集合
        for (int i = 0; i < size; i++) {
            //获取Subscription对象,该对象包含订阅者对象和订阅方法的所有信息
            Subscription subscription = subscriptions.get(i);
            //若找到该订阅者,则移除订阅者
            if (subscription.subscriber == subscriber) {
                subscription.active = false;
                subscriptions.remove(i);
                i--;
                size--;
            }
        }
    }
}

发布事件

EventBus#post()

//发布事件
public void post(Object event) {
    //获取当前线程的PostingThreadState对象
    //postingState对象包含:事件队列、线程状态、是否正在发送的标识等
    PostingThreadState postingState = currentPostingThreadState.get();
    
    //获取事件队列
    List<Object> eventQueue = postingState.eventQueue;
    
    //将事件加入到事件队列中
    eventQueue.add(event);

    //当前事件是否正在发送
    if (!postingState.isPosting) {
        //是否在主线程
        postingState.isMainThread = isMainThread();
        //isPosting设置为true
        postingState.isPosting = true;
        //是否取消
        if (postingState.canceled) {
            throw new EventBusException("Internal error. Abort state was not reset");
        }
        
        try {
            //遍历队列,队列不为null,进入循环
            while (!eventQueue.isEmpty()) {
                //分发事件
                postSingleEvent(eventQueue.remove(0), postingState);
            }
        } finally {
            //重置状态
            postingState.isPosting = false;
            postingState.isMainThread = false;
        }
    }
}

EventBus#postSingleEvent()

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
    //获取事件对象的class
    Class<?> eventClass = event.getClass();
    boolean subscriptionFound = false;

    //是否查看所有的继承关系
    if (eventInheritance) {
        //lookupAllEventTypes()获取父类的所有事件类型
        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) {
            logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
        }
        
        //若没有订阅事件,则发送NoSubscriberEvent
        if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) {
            post(new NoSubscriberEvent(this, event));
        }
    }
}

EventBus#postSingleEventForEventType()

private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?>  eventClass) {

    CopyOnWriteArrayList<Subscription> subscriptions;
    synchronized (this) {
        //获取当前事件的所有订阅者
        subscriptions = subscriptionsByEventType.get(eventClass);
    }

    //若集合不为null
    if (subscriptions != null && !subscriptions.isEmpty()) {
        //遍历集合
        for (Subscription subscription : subscriptions) {
            postingState.event = event;
            postingState.subscription = subscription;
            boolean aborted;
            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;
}

EventBus#postToSubscription()

//处理事件
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
    //根据EventBus线程模式处理对应事件
    switch (subscription.subscriberMethod.threadMode) {          
        case POSTING:
            //默认线程模式,在哪个线程发送事件,就在哪个线程处理事件
            //直接通过反射执行
            invokeSubscriber(subscription, event);
            break;          
        case MAIN:
            //如果是主线程,则直接执行,如果是子线程,则通过Handler切换主线程执行
            if (isMainThread) {
                //主线程中,直接通过反射执行
                invokeSubscriber(subscription, event);
            } else {
                //通过Handler切换到主线程,在进行处理
                mainThreadPoster.enqueue(subscription, event);
            }
            break;
        case MAIN_ORDERED:
            //无论哪个线程,都先加入队列后,通过Handler执行
            if (mainThreadPoster != null) {
                mainThreadPoster.enqueue(subscription, event);
            } else {
                invokeSubscriber(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);
    }
}

//直接通过反射执行
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);
    }
}

EventBus#postSticky()

//发布粘性事件
public void postSticky(Object event) {
    synchronized (stickyEvents) {
        //将事件类型和事件放入stickyEvents中
        stickyEvents.put(event.getClass(), event);
    }
    post(event);
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {

    //...

    //判断订阅方法是否粘性事件
    if (subscriberMethod.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);
        }
    }
}

优秀博客

https://juejin.im/post/5e981905518825085d6d0164#heading-3

https://juejin.im/post/5da97188e51d4524a21c481f#heading-2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值