EventBus3.0源码分析记录

简单使用

  1. 注册
EventBus.getDefault().register(this);
  1. 声明方法(post发送事件的时候,反射调用),不能是private 类型的方法,否则在编译的时候会报错.可以在@Subscribe(threadMode = ThreadMode.MAIN)指定接收事件的时候运行的线程.如果不写,默认是ThreadMode.POSTING
@Subscribe
public void busMethod(String s){
    Log.d(TAG, "busMethod: " + s);
}

@Subscribe(threadMode = ThreadMode.MAIN)
protected void busMethod(Object obj){
        
}
  1. 发送事件,可以传递任何数据类型,对象需要序列化
EventBus.getDefault().post("test obj");
  1. 注销注册
EventBus.getDefault().unregister(this);
四种threadMode

1. ThreadMode.POSTING
post发送事件是在什么线程,接收就在什么线程

2. ThreadMode.MAIN
post发送事件不管在什么线程,接收肯定在主线程(UI线程)

3. ThreadMode.BACKGROUND
post发送事件不管在什么线程,接收肯定在子线程

4. ThreadMode.ASYNC
post不管在什么线程,都会创建新的子线程来接收.

EventBus.getDefault()源码

EventBus(EventBusBuilder builder) {
        //以订阅方法参数类型为key,订阅的类和方法的封装为value
        subscriptionsByEventType = new HashMap<>();
        typesBySubscriber = new HashMap<>();//记录订阅的对象,和方法的参数类型
        stickyEvents = new ConcurrentHashMap<>();
        mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);//主线程Handler
        backgroundPoster = new BackgroundPoster(this);//子线程Handler
        asyncPoster = new AsyncPoster(this);//处理ThreadMode.ASYNC的Handler

        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; //默认是 true
        executorService = builder.executorService;//线程池
    }

EventBus.getDefault的时候是进行了一些数据的初始化

register源码

public void register(Object subscriber) {
        Class subscriberClass = subscriber.getClass();
        List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

通过findSubscriberMethods方法,找到注册类中用来接收消息的方法,

findSubscriberMethods

List findSubscriberMethods(Class subscriberClass) {
        //如果有缓存,直接返回
        List subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }

        if (ignoreGeneratedIndex) { //默认是false
            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;
        }
    }

这里有用Map, List> METHOD_CACHEMap集合把该类的接收事件方法缓存,避免下次重复处理,ignoreGeneratedIndex 默认是false,进入findUsingInfo方法

findUsingInfo

private List findUsingInfo(Class subscriberClass) {
        FindState findState = prepareFindState();//创建FindState 来记录方法的一些信息
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
            findState.subscriberInfo = getSubscriberInfo(findState);
            if (findState.subscriberInfo != null) {  //默认是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.moveToSuperclass();
        }
        return getMethodsAndRelease(findState);
    }

findState.subscriberInfo默认是null,所以就走到findUsingReflectionInSingleClass()方法

findUsingReflectionInSingleClass

private void findUsingReflectionInSingleClass(FindState findState) {
        Method[] methods;
        try {
            methods = findState.clazz.getDeclaredMethods();//获取该类所有的方法
        } catch (Throwable th) {
            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注释
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class); 
                    if (subscribeAnnotation != null) {  //@Subscribe注释不为 null 才满足
                        Class eventType = parameterTypes[0];
                        if (findState.checkAdd(method, eventType)) {

                            //获取接收事件方法的 threadMode 类型
                            ThreadMode threadMode = subscribeAnnotation.threadMode();

                            //把方法名,参数类型, threadMode类型都封装到SubscriberMethod对象,用findState来管理
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                        }
                    }
               ...
    }

这里就是找到注册类中具体的方法,进行一些封装并且记录起来,然后结束这个方法,进入到return getMethodsAndRelease(findState);最后一个方法,返回一个List集合

private List getMethodsAndRelease(FindState findState) {
        List 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;
    }

getMethodsAndRelease() 方法就是清空findState对象里面的一些数据,释放内存,并且这里使用了FindState[] FIND_STATE_POOL ,FindState[] 数组来循环利用,避免销毁更多的内存

得到这些接收事件的方法之后,遍历这个保存事件方法的List集合,进行subscribe()订阅.

subscribe源码

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
        Class eventType = subscriberMethod.eventType;//记录订阅方法的参数类型
        //newSubscription 记录订阅类和方法
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        CopyOnWriteArrayList subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            //以订阅方法参数类型为key,CopyOnWriteArrayList为value
            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> subscribedEvents = typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList<>();
            //订阅的类为 key ,ArrayList 为value
            typesBySubscriber.put(subscriber, subscribedEvents);
        }
        //记录参数类型
        subscribedEvents.add(eventType);

        ...
        //sticky粘性事件的一些处理
    }

具体的订阅就是用Map, CopyOnWriteArrayList> subscriptionsByEventType,一个Map集合,以订阅方法参数类型为key,当前订阅的类的信息,和接收事件的方法信息(方法名字,参数类型,接收线程模式,优先级..等等)为value保存,后面post发送事件的时候,根据参数类型,从上面subscribe订阅时候保存的subscriptionsByEventType集合,获取到对应的类信息和方法,反射调用

post源码

public void post(Object event) {
        PostingThreadState postingState = currentPostingThreadState.get();
        List eventQueue = postingState.eventQueue;
        //把传递的对象添加List集合队列
        eventQueue.add(event);

        if (!postingState.isPosting) { //默认是fasle,这里满足
            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;
            }
        }
    }
 
 

把post要传递的对象添加eventQueue这个List集合队列里面,然后到while 里面循环遍历,调用postSingleEvent发送事件消息,postSingleEvent方法会调用postSingleEventForEventType方法来完成.

postSingleEventForEventType

 private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class eventClass) {
        CopyOnWriteArrayList subscriptions;
        synchronized (this) {
            //这里就根据 post要传递的参数类型,获取到对应的类和方法的信息
            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;
    }

可以看到,这里是根据要传递的参数类型(EventBus.getDefault().post(传递参数)),来获取到上面订阅的时候保存的类和方法的信息,然后遍历,调用postToSubscription方法,去发送事件消息

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

判断订阅方法的threadMode模式,利用不同线程的Handler进行线程切换,做不同的处理.最后都是调用invokeSubscriber方法通过反射调用到接收事件通知的方法来完成事件的通知过程..

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

unregister注销注册源码

//订阅的类为 key ,接收事件方法的参数类型的List集合 为value
//typesBySubscriber.put(subscriber, subscribedEvents);

public synchronized void unregister(Object subscriber) {
        //typesBySubscriber订阅事件的时候,保存的信息
        List> 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());
        }
    }

注销注册就是从对应的Map集合里面把对应的订阅者类,删除掉.

unsubscribeByEventType

private void unsubscribeByEventType(Object subscriber, Class eventType) {
        //根据参数类型,获取到对应的订阅者类的集合
        List 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--;
                }
            }
        }
    }

你可能感兴趣的:(EventBus3.0源码分析记录)