EventBus源码分析

###EventBus简单使用
EventBus简单介绍

  • 1.Androd 事件发布/订阅框架
  • 2.事件传递即可适用于Android四大组件间通讯
  • 3.EventBus的有点是代码简洁,使用简单,并将事件发布和订阅充分讲解
    这里写图片描述

Handler的使用

  private Handler handler;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message=handler.obtainMessage();
                message.arg1=1;
                message.obj="消息信息";
                handler.sendMessage(message);
                System.out.println(Thread.currentThread().getName());
            }
        });
        new MyThread().start();
    }
    //  java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    private class MyThread extends Thread{
        @Override
        public void run() {
            Looper.prepare();
            handler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("msg.what=="+msg.what+"wsg.obj=="+msg.obj);

                }
            };
            Looper.loop();
        }
    }

EventBus流程图
这里写图片描述

github官网:https://github.com/greenrobot/EventBus

依赖:compile 'org.greenrobot:eventbus:3.1.1’

eventBus的用法

public class Test extends Activity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              EventBus.getDefault().post(new MyBusEvent("我是EventBus"));
          }
      });
    }

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

    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }
    @Subscribe(threadMode= ThreadMode.MAIN)
    public void onMessageEvent(MyBusEvent event){
        Toast.makeText(this,event.message,Toast.LENGTH_SHORT).show();
    }
}

1.定义事件event
2.准备订阅者
3.订阅者同时需要在总线上注册和注销自己
4.发送事件

###源码分析
1.EventBus.getDefault()源码分析

   //同步锁单例模式
   public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }
   //构造函数
    public EventBus() {
        this(DEFAULT_BUILDER);
    }
 private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();

  EventBus(EventBusBuilder builder) {
         //event为key,以Subscription为value.找到我们对应的订阅者
        subscriptionsByEventType = new HashMap<>();
        //以Subscriber为key,以types为value,反注册和注册
        typesBySubscriber = new HashMap<>();
        //粘性事件,当我们发送event,再注册粘性事件,这个粘性会收到之前的事件
        stickyEvents = new ConcurrentHashMap<>();
        //poster就是负责线程间调度
        mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
        //后台运行,取出所有然后事件分发
        backgroundPoster = new BackgroundPoster(this);
        //取出一个,然后事件分发
        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;
    }

HandlerPoster源码分析

 HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
        super(looper);
        this.eventBus = eventBus;
        //poster在handler.message中存在最大的时间值
        this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
        queue = new PendingPostQueue();
    }
 public void handleMessage(Message msg) {
        boolean rescheduled = false;
        try {
            long started = SystemClock.uptimeMillis();
            while (true) { 
          //PendingPost 只有两个方法obtainPendingPost获得PendingPost和releasePendingPost释放
                PendingPost pendingPost = queue.poll();
                if (pendingPost == null) {
                    synchronized (this) {
                      pendingPost = queue.poll();
                        if (pendingPost == null) {
                          //handlerActive 代表是否运行成功
                            handlerActive = false;
                            return;
                        }
                    }
                }
                //分发事件
                eventBus.invokeSubscriber(pendingPost);
                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;
        }

2.Subscribe源码分析

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    //线程模式
    ThreadMode threadMode() default ThreadMode.POSTING;
   //是否为粘性事件   粘性事件:事件消费者在事件发布之后才注册的也能接受到改事件的特殊性,如粘性广播,在广播接受后会保存刚刚发送的广播
    boolean sticky() default false;
   //优先级
    int priority() default 0;
}

ThreadMode源码分析

public enum ThreadMode {
   //订阅者将在同一个线程中调用,该线程正在发布事件。这是默认的。事件交付意味着最少的开销,因为它避免了完全的线程切换。因此,对于已知的完成的简单任务来说,这是一个非常短的时间,而不需要主线程。使用此模式的事件处理程序必须快速返回,以避免阻塞发布线程,这可能是主线程。
    POSTING,

//用户将在Android的主线程(有时被称为UI线程)调用。如果发布线程是主线程,则将直接调用事件处理程序方法。使用此模式的事件处理程序必须快速返回以避免阻塞主线程
    MAIN,
    
//用户将在后台线程中调用。如果发布线程不是主线程,事件处理程序方法将直接在发布线程中调用。如果发布线程是主线程,EventBus使用一个单独的后台线程,它将按顺序交付所有事件。使用此模式的事件处理程序应该尝试快速返回,以避免阻塞后台线程。
    BACKGROUND,

  //事件处理程序方法应该使用这种模式,如果它们的执行可能需要一些时间,例如网络访问。避免在同一时间触发大量的异步处理程序方法来限制并发线程的数量。EventBus使用线程池有效地重用已完成的异步事件处理程序通知中的线程。
    ASYNC
}

3.register源码分析

    public void register(Object subscriber) {
      //获得反射类
        Class<?> subscriberClass = subscriber.getClass();
        //找到订阅者方法所有集合
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

subscriberMethodFinder.findSubscriberMethods(subscriberClass)源码分析

 List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        //判断是否有缓存,有缓存直接返回
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
          //默认是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;
        }
    }

findUsingInfo源码分析

  private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
  //获取FindState 对象
        FindState findState = prepareFindState();
        //赋值操作
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
        //获得订阅者信息
            findState.subscriberInfo = getSubscriberInfo(findState);
            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.moveToSuperclass();
        }
        //方法释放
        return getMethodsAndRelease(findState);
    }

//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();
            //判断是否是public和是否可以忽略
            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) {
                        Class<?> eventType = parameterTypes[0];
                        if (findState.checkAdd(method, eventType)) {
                        //获得线程模式
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                        }
                    }
                
    }

prepareFindState源码分析

 private FindState prepareFindState() {
        synchronized (FIND_STATE_POOL) {
            for (int i = 0; i < POOL_SIZE; i++) {
            //for循环
                FindState state = FIND_STATE_POOL[i];
                if (state != null) {
                    FIND_STATE_POOL[i] = null;
                    return state;
                }
            }
        }
        //如果为空则直接new
        return new FindState();
    }

subscribe(subscriber, subscriberMethod);源码分析

 private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
        Class<?> eventType = subscriberMethod.eventType;
        //封装了订阅者
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        //可读写
        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);
            }
        }
        //获得大小
        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);
        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);
            }
        }
    }
>首先判断是否有注册过改事件
然后按照优先级加入到suscriptionsByEventType的value的List中
然后添加到typesBySubscriber的value中的List中
分发事件 checkPostStickyEventToSubscription

checkPostStickyEventToSubsrciption源码分析

   private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
   //如果粘性事件不为空
     if (stickyEvent != null) {
     //Looper.getMainLooper() == Looper.myLooper()判断是主线程
 postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
        }
    }

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

4.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;
            }
        }
    }
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通;、本 3项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看ReadmE.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、资 1源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READMe.m文件(如d有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值