1,分析androidEventbus的注册源代码:

我们在使用androidEventbus的第一步是注册eventbus,如下代码:
    1. EventBus.getDefault().register(this);
首先获取eventbus对象,采用单利模式实现获取对象:
Eventbus.java里面
    1. public static EventBus getDefault() {
    2. if (sDefaultBus == null) {
    3. synchronized (EventBus.class) {
    4. if (sDefaultBus == null) {
    5. sDefaultBus = new EventBus();
    6. }
    7. }
    8. }
    9. return sDefaultBus;
    10. }


然后是:
    1. public void register(Object subscriber) {
    2. if (subscriber == null) {
    3. return;
    4. }
    5. synchronized (this) {
    6. mMethodHunter.findSubcribeMethods(subscriber);
    7. }
    8. }


跟踪到mMethodHunter.findSubcribeMethods(subscriber);继续往下看:
mMethodHunter在代码头部注册:
    1. /**
    2. * the subscriber method hunter, find all of the subscriber's methods
    3. * annotated with @Subcriber
    4. */
    5. SubsciberMethodHunter mMethodHunter =newSubsciberMethodHunter(mSubcriberMap);
用于查找所有使用@subcriber的注解方法
然后我们跟到findSubcribeMethods(subscriber)里面看看:
遍历
    1. public void findSubcribeMethods(Object subscriber) {
    2. if (mSubcriberMap == null) {
    3. throw new NullPointerException("the mSubcriberMap is null. ");
    4. }
    5. Class<?> clazz = subscriber.getClass();
    6. // 查找类中符合要求的注册方法,直到Object类
    7. while (clazz != null && !isSystemCalss(clazz.getName())) {
    8. final Method[] allMethods = clazz.getDeclaredMethods();
    9. for (int i = 0; i < allMethods.length; i++) {
    10. Method method = allMethods[i];
    11. // 根据注解来解析函数
    12. Subscriber annotation = method.getAnnotation(Subscriber.class);
    13. if (annotation != null) {
    14. // 获取方法参数
    15. Class<?>[] paramsTypeClass = method.getParameterTypes();
    16. // 订阅函数只支持一个参数
    17. if (paramsTypeClass != null && paramsTypeClass.length == 1) {
    18. Class<?> paramType = convertType(paramsTypeClass[0]);
    19. EventType eventType = new EventType(paramType, annotation.tag());
    20. TargetMethod subscribeMethod = new TargetMethod(method, eventType,
    21. annotation.mode());
    22. subscibe(eventType, subscribeMethod, subscriber);
    23. }
    24. }
    25. } // end for
    26. // 获取父类,以继续查找父类中符合要求的方法
    27. clazz = clazz.getSuperclass();
    28. }
    29. }


然后再 subscibe(eventType, subscribeMethod, subscriber);方法里面的代码:
mSubcriberMap是个map集合
 
    1. /**
    2. * the event bus's subscriber's map
    3. */
    4. Map<EventType, CopyOnWriteArrayList<Subscription>> mSubcriberMap;

    1. /**
    2. * 按照EventType存储订阅者列表,这里的EventType就是事件类型,一个事件对应0到多个订阅者.
    3. *
    4. * @param event 事件
    5. * @param method 订阅方法对象
    6. * @param subscriber 订阅者
    7. */
    8. private void subscibe(EventType event, TargetMethod method, Object subscriber) {
    9. CopyOnWriteArrayList<Subscription> subscriptionLists = mSubcriberMap.get(event);
    10. if (subscriptionLists == null) {
    11. subscriptionLists = new CopyOnWriteArrayList<Subscription>();
    12. }
    13. Subscription newSubscription = new Subscription(subscriber, method);
    14. if (subscriptionLists.contains(newSubscription)) {
    15. return;
    16. }
    17. subscriptionLists.add(newSubscription);
    18. // 将事件类型key和订阅者信息存储到map中
    19. mSubcriberMap.put(event, subscriptionLists);
    20. }
 
到这里就可以看到register就是遍历所有注解@Subcriber的方法,并将事件类型key和订阅者信息存储在map中去。这点很类似eventbus代码中register,只不过eventbus是以以onEvent开头的方法去进行查找,而androideventbus是以@subcriber去进行遍历检索,但最终都是将事件类型key和订阅者信息存储在map中去。

【第四篇】androidEventbus源代码阅读和分析的更多相关文章

  1. 【第五篇】androidEventbus源代码阅读和分析之发送粘性事件和接收粘性事件代码分析

    代码里面发送粘性事件代码如下: // 发送Sticky事件 EventBus.getDefault().postSticky(new User("soyoungboy", &quo ...

  2. 【第五篇】androidEventbus源代码阅读和分析之unregister代码分析

    代码里面注销eventbus一般我们会在onDestory里面这么写: EventBus.getDefault().unregister(this); 然后走到unregister里面去看看: /** ...

  3. Tools - 源代码阅读分析工具Source Insight

    简介 https://www.sourceinsight.com/ Source Insight是一个面向项目开发的程序编辑器和代码浏览器,可以分析C/C++.C#.Java.Python等语言源代码 ...

  4. 非常好!!!Linux源代码阅读——中断【转】

    Linux源代码阅读——中断 转自:http://home.ustc.edu.cn/~boj/courses/linux_kernel/2_int.html 目录 为什么要有中断 中断的作用 中断的处 ...

  5. 【转】Tomcat总体结构(Tomcat源代码阅读系列之二)

    本文是Tomcat源代码阅读系列的第二篇文章,我们在本系列的第一篇文章:在IntelliJ IDEA 和 Eclipse运行tomcat 7源代码一文中介绍了如何在intelliJ IDEA 和 Ec ...

  6. CI框架源代码阅读笔记5 基准測试 BenchMark.php

    上一篇博客(CI框架源代码阅读笔记4 引导文件CodeIgniter.php)中.我们已经看到:CI中核心流程的核心功能都是由不同的组件来完毕的.这些组件类似于一个一个单独的模块,不同的模块完毕不同的 ...

  7. [转]madwifi无线网卡源代码阅读

    转自:http://xiyong8260.blog.163.com/blog/static/66514621200892465922669/ 在我的Doctor课题研究中,基于ARF协议设计了一个改进 ...

  8. 非常好!!!Linux源代码阅读——内核引导【转】

    Linux源代码阅读——内核引导 转自:http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html 目录 Linux 引导过程综述 BI ...

  9. 【block第四篇】实现

    -------------------------------------------欢迎查看block连载博客[专栏]--------------------------------------[b ...

随机推荐

  1. WinForm 基础

    今天,我开始学习了WinForm.WinForm是客户端程序制作 - C/S,它必须在.NET Framework框架上运行 . 开始,我先学习了一下WinForm的常用窗体属性. 布局:AutoSc ...

  2. 生成元(Digit Generator,ACM/ICPC Seoul 2005,UVa 1583)

    #include<cstdio>#include<cstdlib>#include<cstring>using namespace std;int t, n, a, ...

  3. iOS 解决文本(uitextfield/uitextView)在中间显示而不在顶部显示 问题

    在对应的控制器中设置下面属性 self.automaticallyAdjustsScrollViewInsets = NO; 这样就好了.

  4. iOS 10 / Swift 3.0 / XCode 8 总结

    1,iOS10 新增的privacy settings iOS10添加了新的权限控制范围 如果你尝试访问这些隐私数据时得到如下错误: > This app has crashed because ...

  5. Python--变量作用域

    变量作用域: 一般在函数体外定义的变量成为全局变量,在函数内部定义的变量称为局部变量. 全局变量所有作用域都可读,局部变量只能在本函数可读 函数在读取变量时,优先读取函数本身自有的局部变量,再去读全局 ...

  6. CachedRowSet的用法

    String sql="select item_code from xt_dictionary_item where type_id='32' and parent_itemid='0' o ...

  7. HTTP状态码含义

    本文内容是在有道云笔记中找到的,已不知复制自何处,抱歉 一些常见的状态代码为:200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务器暂时不可用   1xx(临时响应) 用于表 ...

  8. gulp4个基础API

    Gulp.src(globs[, options]) 此接口会匹配工作目录下指定规则的文件并返回提供给下一个插件管道使用.其中globs就是匹配格式,options是一些额外参数. gulp.src( ...

  9. NetPayClient for PHP使用说明

    名 称 放置的路径 用 途 SecssUtil.class.php 根据项目工程的需要放置对应路径下 支持PHP5.4.8及以上版本 用于提供商户签名.验签.加密.解密.文件验签等方法调用 Mer.p ...

  10. Java中三种常见的注释(注解) Annotation

    Java为我们提供了三种Annotation方便我们开发. 1 Override-函数覆写注解 如果我们想覆写Object的toString()方法,请看下面的代码: class Annotation ...